C++登录系统文件读取异常:跨行数据混读问题求助
登录系统数据混读问题排查与解决
问题说明
开发的登录系统中,账号文件按username、password、email、address、phone number顺序存储用户数据,代码读取文件行存入struct后放入vector,验证用户输入的账号密码时,第一行数据读取正常,但第二行数据会混读第一行内容,预期登录后显示包含用户名的欢迎信息,现需解决该数据混读问题。
相关代码
struct CargoAccData { string email; string address; string username; string password; string phoneNumber; }; void LogInSystem::LogInCargo() { string fileName = "cargoAccount.txt"; ifstream cargoAccFile(fileName); Validation val; string attemptedUsername; string attemptedPassword; bool loopControl = true; int count = 0; if (cargoAccFile.is_open()) { string line; while (!cargoAccFile.eof()) { getline(cargoAccFile, line); count++; } } cargoAccFile.close(); ifstream cargoAccFile2(fileName); std::vector<CargoAccData> accounts; while (loopControl) { if (!cargoAccFile2) { cout << "This file doesn't exist \n"; loopControl = false; } for (size_t i = 0; i < count; i++) { CargoAccData account; cargoAccFile2 >> account.email >> account.address >> account.username >> account.password >> account.phoneNumber; accounts.push_back(account); } cout << "Please Enter your Username: \n"; cin >> attemptedUsername; cout << "\nPlease Enter Your Password: \n"; cin >> attemptedPassword; int z = 0; bool isCorrect = false; while (z < count) { cout << accounts[z].username << endl; cout << accounts[z].password << endl; if (attemptedUsername == accounts[z].username && attemptedPassword == accounts[z].password) { cout << "Welcome to the E-market {" << attemptedUsername << "}" << endl; loopControl = false; isCorrect = true; break; } else { z++; } } if (isCorrect == true) { // This is where the main profile will lead to } else { cout << "Username or password incorrect, Try Again" << endl; } } }
账号文件内容
test test test test test test test test mrjoeyrules VerySecure1 mrjoeyrules@gmail.com 3 07879652851
CLI输出

问题根源分析
- 字段顺序不匹配:struct定义的字段顺序为
email、address、username、password、phoneNumber,但文件中用户数据的存储顺序是username、password、email、address、phone number,读取时赋值顺序完全颠倒,直接导致数据错位。 - 行数统计错误:使用
while(!cargoAccFile.eof())统计行数会多计算一行(EOF标志在读取失败后才会触发,最后一次getline失败后count仍会自增),导致后续循环尝试读取超出文件内容的脏数据。 - 重复读取逻辑错误:外层
while(loopControl)循环内每次都会重新读取文件到vector,导致vector中累积重复数据,二次验证时会读到之前的旧数据。
解决方案
1. 修正字段读取顺序
按照文件存储顺序username、password、email、address、phone number调整读取赋值的顺序,修改读取代码为:
cargoAccFile2 >> account.username >> account.password >> account.email >> account.address >> account.phoneNumber;
也可以直接调整struct的字段顺序与文件一致,从根源避免顺序错误。
2. 修复行数统计逻辑
使用正确的getline循环统计行数,避免多计数:
if (cargoAccFile.is_open()) { string line; while (getline(cargoAccFile, line)) { count++; } }
3. 调整文件读取时机
将文件读取到vector的逻辑移到外层while(loopControl)循环之外,只读取一次,避免重复累积数据:
// 读取文件到vector的代码移到这里 std::vector<CargoAccData> accounts; if (cargoAccFile2.is_open()) { for (size_t i = 0; i < count; i++) { CargoAccData account; cargoAccFile2 >> account.username >> account.password >> account.email >> account.address >> account.phoneNumber; accounts.push_back(account); } cargoAccFile2.close(); } while (loopControl) { // 这里只保留登录验证逻辑,不再重复读取文件 cout << "Please Enter your Username: \n"; cin >> attemptedUsername; cout << "\nPlease Enter Your Password: \n"; cin >> attemptedPassword; // ... 后续验证逻辑不变 }
修改后完整示例代码
struct CargoAccData { string username; string password; string email; string address; string phoneNumber; }; void LogInSystem::LogInCargo() { string fileName = "cargoAccount.txt"; ifstream cargoAccFile(fileName); Validation val; string attemptedUsername; string attemptedPassword; bool loopControl = true; int count = 0; // 正确统计文件行数 if (cargoAccFile.is_open()) { string line; while (getline(cargoAccFile, line)) { count++; } cargoAccFile.close(); } else { cout << "This file doesn't exist \n"; return; } ifstream cargoAccFile2(fileName); std::vector<CargoAccData> accounts; // 仅读取一次文件到vector if (cargoAccFile2.is_open()) { for (size_t i = 0; i < count; i++) { CargoAccData account; // 按文件存储顺序读取字段 cargoAccFile2 >> account.username >> account.password >> account.email >> account.address >> account.phoneNumber; accounts.push_back(account); } cargoAccFile2.close(); } while (loopControl) { cout << "Please Enter your Username: \n"; cin >> attemptedUsername; cout << "\nPlease Enter Your Password: \n"; cin >> attemptedPassword; int z = 0; bool isCorrect = false; while (z < accounts.size()) { if (attemptedUsername == accounts[z].username && attemptedPassword == accounts[z].password) { cout << "Welcome to the E-market {" << attemptedUsername << "}" << endl; loopControl = false; isCorrect = true; break; } else { z++; } } if (!isCorrect) { cout << "Username or password incorrect, Try Again" << endl; } } }
内容的提问来源于stack exchange,提问作者mrjoeyrules
相关产品推荐
相关产品推荐

