引入流时C++数据文件未正确读取?

C++ data file not reading correctly when introducing ofstream?

本文关键字:读取 文件 数据 C++      更新时间:2023-10-16

好的,这将是一个很长的时间...

解释项目应该做什么:

我的最后一个项目是一个银行柜员系统,它将所有与帐户相关的数据存储在文本文件中。
有问题的文件"帐户.txt">是存储所有帐户数据的位置。它是可读和写的,当引入流时行为奇怪......

"帐户.txt">文件的格式如下

01481 554-00-8336简·琼斯
1483 N.领域第二大道,伯灵顿,佛蒙特州 05401 564 425 5052 02650 727-22-1072詹妮弗·阿姆斯特朗
1450
W.主路,伯灵顿,VT 05401


202

545 5485

它继续重复相同的有序信息集......

该程序的核心部分之一依赖于将这些值读取到 5 个单独的数组中,每个数组都与数据类型(名称、地址等(有关。

我将转储整个程序,因为我认为可能需要解决问题,只需了解有问题的主要函数是addAccount((并且位于底部。

请注意,此函数的目的是将整个帐户.txt逐行文件读取到内存中,确定用于存储文件的数组在什么时候被空数据填充(课程讲师告诉我们将数组大小设为 100,这意味着读入数组的大部分数据都是空白空间(从用户那里获取所需的帐户信息, 更新内存中的文件,然后重写文件...

另请注意,文件格式是由课程讲师预先确定的

代码:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
const int TELLERS_SIZE = 5;
const int ACCOUNTS_SIZE = 100;
const string TELLERS_FILE = "tellers.txt";
const string ACCOUNTS_FILE = "accounts.txt";
int beginMenu();
bool login(string fileName);
int baseMenu();
void searchAccount(string fileName);
void addAccount(string fileName);
int main() {
int beginSelection;
do {
beginSelection = beginMenu();
if (beginSelection == 2) {
return 0;
}
bool loginIsTrue = login(TELLERS_FILE);
while (loginIsTrue) {
int baseSelection = baseMenu();
if (baseSelection == 1) {
addAccount(ACCOUNTS_FILE);
}
if (baseSelection == 4) {
searchAccount(ACCOUNTS_FILE);
}
if (baseSelection == 8) {
loginIsTrue = false;
}
}
} while (beginSelection == 1);
}
// Print the fisrt menu and return selection
int beginMenu() {
// Establish return value and validation
int menuSelection;
string userInput;
bool menuSelectionIsValid = false;
// Print options
do {
cout << "n";
cout << "[1] Login" << "n";
cout << "[2] Quit" << "n";
cout << "Please enter a selection";
cout << "n";
getline(cin, userInput);
// Validate input
if (userInput == "1") {
menuSelectionIsValid = true;
menuSelection = 1;
}
else if (userInput == "2") {
menuSelectionIsValid = true;
menuSelection = 2;
}
else {
cout << "Invalid input!" << "n";
}
} while (!menuSelectionIsValid);
return menuSelection;
}
// Perform login and return true or false
bool login(string fileName) {
// Establish variables
string username[TELLERS_SIZE];
string password[TELLERS_SIZE];
string usernameInput;
string passwordInput;
bool loginIsValid = false;
// Establish fin
ifstream fin(fileName);
if (!fin.is_open()) {
cout << "File cannot be opened " << fileName << "n";
return false;
}
// Read tellers.dat
for (int i = 0; i < TELLERS_SIZE; i++) {
fin >> username[i];
fin >> password[i];
}
// Read user input
cout << "n";
cout << "Username: ";
getline(cin, usernameInput);
cout << "Password: ";
getline(cin, passwordInput);
// Verify login information
for (int i = 0; i < TELLERS_SIZE; i++) {
if (username[i] == usernameInput && password[i] == passwordInput) {
cout << "Login succesful" << "n";
loginIsValid = true;
return true;
}
}
// Inform user of error
cout << "Invalid username or password!" << "n";
return false;
}
// Print base functions menu and return selection
int baseMenu () {
// Establish return value and validation
int menuSelection;
string userInput;
bool menuSelectionIsValid = false;
do {
// Print options
cout << "n";
cout << "[1] Add Account" << "n";
cout << "[2] Remove Account" << "n";
cout << "[3] Update Account" << "n";
cout << "[4] Search Account" << "n";
cout << "[5] Make A Deposit" << "n";
cout << "[6] Make A Withdrawal" << "n";
cout << "[7] Check Balance" << "n";
cout << "[8] Logout" << "n";
cout << "Please enter a selection";
cout << "n";
getline(cin, userInput);
// Validate input
if (userInput == "1") {
menuSelectionIsValid = true;
menuSelection = 1;
}
else if (userInput == "2") {
menuSelectionIsValid = true;
menuSelection = 2;
}
else if (userInput == "3") {
menuSelectionIsValid = true;
menuSelection = 3;
}
else if (userInput == "4") {
menuSelectionIsValid = true;
menuSelection = 4;
}
else if (userInput == "5") {
menuSelectionIsValid = true;
menuSelection = 5;
}
else if (userInput == "6") {
menuSelectionIsValid = true;
menuSelection = 6;
}
else if (userInput == "7") {
menuSelectionIsValid = true;
menuSelection = 7;
}
else if (userInput == "8") {
menuSelectionIsValid = true;
menuSelection = 8;
}
else {
cout << "Invalid input!" << "n";
}
} while (!menuSelectionIsValid);
return menuSelection;
}
// Locate account and print relevant information
void searchAccount(string fileName) {
// Establish arrays
string accountNumber[ACCOUNTS_SIZE];
string accountSSN[ACCOUNTS_SIZE];
string accountName[ACCOUNTS_SIZE];
string accountAddress[ACCOUNTS_SIZE];
string accountPhone[ACCOUNTS_SIZE];
// Establish validation variables
string userInput;
bool accountFound = false;
// Establish and validate fin
ifstream fin(fileName);
if (!fin.is_open()) {
cout << "File cannot be opened " << fileName << "n";
}
// Get desired account number
cout << "n";
cout << "Account number: ";
getline(cin, userInput);
// Read information from file
for (int i = 0; i < ACCOUNTS_SIZE; i++) {
getline(fin, accountNumber[i]);
getline(fin, accountSSN[i]);
getline(fin, accountName[i]);
getline(fin, accountAddress[i]);
getline(fin, accountPhone[i]);
}
// Search for account
for (int i = 0; i < ACCOUNTS_SIZE; i++) {
if (accountNumber[i] == userInput && userInput != "") {
accountFound = true;
}
// Display account information
if (accountFound == true) {
cout << "Account Found" << "n";
cout << "Displaying account information" << "n" << "n";
cout << accountNumber[i] << "n";
cout << accountSSN[i] << "n";
cout << accountName[i] << "n";
cout << accountAddress[i] << "n";
cout << accountPhone[i] << "n";
break;
}
}
// Inform user that account doesnt exist
if (accountFound == false) {
cout << "Unable to find account: " << userInput << "n";
}
}
void addAccount(string fileName) {
string accountNumber[ACCOUNTS_SIZE];
string accountSSN[ACCOUNTS_SIZE];
string accountName[ACCOUNTS_SIZE];
string accountAddress[ACCOUNTS_SIZE];
string accountPhone[ACCOUNTS_SIZE];
ifstream fin(fileName);
// ofstream fout(fileName);
string userAccountNumber;
string userAccountSSN;
string userAccountName;
string userAccountAddress;
string userAccountPhone;
bool accountNumberIsTaken = true;
for (int i = 0; i < ACCOUNTS_SIZE; i++) {
getline(fin, accountNumber[i]);
getline(fin, accountSSN[i]);
getline(fin, accountName[i]);
getline(fin, accountAddress[i]);
getline(fin, accountPhone[i]);
}
do {
accountNumberIsTaken = false;
cout << "n";
cout << "Enter desired account number: ";
getline(cin, userAccountNumber);
for (int i = 0; i < ACCOUNTS_SIZE; i++) {
if (userAccountNumber == accountNumber[i] || userAccountNumber == "") {
cout << "That account number is already in use" << "n";
accountNumberIsTaken = true;
break;
}
}
} while (accountNumberIsTaken);
/*
cout << "Enter SSN: ";
getline(cin, userAccountSSN);
cout << "Enter full name: ";
getline(cin, userAccountName);
cout << "Enter address: ";
getline(cin, userAccountAddress);
cout << "Enter phone number: ";
getline(cin, userAccountPhone);
for (int i = 0; i < ACCOUNTS_SIZE; i++) {
if (accountNumber[i] == "") {
cout << "empty space found at" << i;
accountNumber[i] = userAccountNumber;
accountSSN[i] = userAccountSSN;
accountName[i] = userAccountName;
accountAddress[i] = userAccountAddress;
accountPhone[i] = userAccountPhone;
break;
}
}
for (int i = 0; i < ACCOUNTS_SIZE; i++) {
fout << accountNumber[i] << "n";
fout << accountSSN[i] << "n";
fout << accountName[i] << "n";
fout << accountAddress[i] << "n";
fout << accountPhone[i] << "n";
}
*/
}

问题:

基本代码,没有任何注释,根本不起作用。

依赖于读取"accounts.txt">accountSearch((和addAccount((函数都会报告"accounts.dat">上明显存在的帐号不存在。

在注释掉流 fout(文件名(;以及依赖于写入文件并对"accounts.txt">文件进行轻微更改保存更改的addAccount((的下半部分后,事情又开始工作了

该项目是在Visual Studio 2019中编写的。

如果这是一个糟糕的解释,请道歉。如有必要,请要求澄清。

您不能同时将filename作为ifstreamofstream打开!因此,将fout的声明/构造函数移动到读取fin的代码之后,如下所示:

void addAccount(string fileName) {
string accountNumber[ACCOUNTS_SIZE];
string accountSSN[ACCOUNTS_SIZE];
string accountName[ACCOUNTS_SIZE];
string accountAddress[ACCOUNTS_SIZE];
string accountPhone[ACCOUNTS_SIZE];
ifstream fin(fileName);
// ofstream fout(fileName); /// CANNOT BE HERE!
string userAccountNumber;
///... Here, have all your reading and input code (as it is) …
///...
///... Finished reading, etc., so CLOSE "fin" then get the "fout" …
fin.close();
ofstream fout(fileName); // NOW we can create the output stream!
///... and use your existing code to do the writing
for (int i = 0; i < ACCOUNTS_SIZE; i++) {
fout << accountNumber[i] << "n";
fout << accountSSN[i] << "n";
fout << accountName[i] << "n";
fout << accountAddress[i] << "n";
fout << accountPhone[i] << "n";
}
fout.close(); /// When finished, CLOSE the file!
}