You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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输出

CLI输出截图

问题根源分析

  1. 字段顺序不匹配:struct定义的字段顺序为email、address、username、password、phoneNumber,但文件中用户数据的存储顺序是username、password、email、address、phone number,读取时赋值顺序完全颠倒,直接导致数据错位。
  2. 行数统计错误:使用while(!cargoAccFile.eof())统计行数会多计算一行(EOF标志在读取失败后才会触发,最后一次getline失败后count仍会自增),导致后续循环尝试读取超出文件内容的脏数据。
  3. 重复读取逻辑错误:外层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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 22:32:39