引入流时C++数据文件未正确读取?
C++ data file not reading correctly when introducing ofstream?
好的,这将是一个很长的时间...
解释项目应该做什么:
我的最后一个项目是一个银行柜员系统,它将所有与帐户相关的数据存储在文本文件中。
有问题的文件"帐户.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
作为ifstream
和ofstream
打开!因此,将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!
}
- 使用新行和不使用新行读取文件
- 读取文件并输入到矢量中
- 读取文件的最后一行并输入到链接列表时出错
- 为什么在读取文件大小时文件IO速度会发生变化
- 读取文件时运行时的未知行为
- 如何逐行读取文件,每行中的内容都用空格分隔并将其写入新文件中
- 读取文件中所有可能的十六进制 16 字节序列并打印每个序列
- C++ 读取文件读取文件不正确
- 读取文件并将其存储在unordered_map中时出现问题
- 读取文件时无法使用 OpenMP 获得加速
- 使用istringstearm和get行缓慢读取文件
- 如何继续读取不同功能中的文件,而不是从头开始再次读取文件?
- 读取文件时引发异常
- 从标准输入读取文件后读取用户输入
- 在读取文件后重置句柄
- 如何在C++编译时读取文件?
- std::ifstream 在读取文件中最后一项时设置 eofbit,但仅在读取数值类型时发生
- 读取文件在第二次调用时返回INVALID_HANDLE
- 通过指针读取文件
- 逐行读取文件,并将数据插入变量和数组中