c++ - .txt 到 vector<struct> 故障

标签 c++ input vector struct

我目前正在完成学校的考试项目。我要创建一个用户数据库,您可以在其中通过帐户登录并向系统中的其他人发送消息。但是有几个错误,直到现在我还没有发现。程序第一次执行时,会将用户数据库复制成.txt格式,像这样(userlist.txt),

created: Sun May 13 18:41:08 2012
mod_date: Sun May 13 18:41:08 2012


ID:1
created:Sun May 13 18:41:08 2012
name:admin
password:Admin1
security level:2
status:active

这很好用,因为它是从 vector 中复制的。但是后来我不得不做相反的过程,当我第二次打开程序时(除非我删除了 userlist.txt), vector 似乎包含了错误的信息。这很难解释,因此我将源代码上传到 mediafire。我猜总共有 600 行代码,但我认为只有 main.cpp 和 dbmani.h 中的函数 login() 和 writedb() ( vector 在类中定义的地方)才能看到问题.代码的第一行在这里(如果存在, vector 将从 userlist.txt 接收输入),希望您不必下载我的所有源代码,

int main()
{

    system("mkdir messages");
    ifstream inFile;
    inFile.open("userlist.txt");


    if(inFile.good())   // If userlist.txt exist - therefore an existing user database exist.
    {
        // ADD DATE OF MODIFICATION
        cout << "USERLIST FOUND, READING USERS.\n\n";
        userstats tempBuffer;
        int userCount = -1;
        int overCount = 0;
        string buffer;

        while(getline(inFile, buffer))
        {
            if (0 == buffer.find("ID:"))
            {
                userCount++;

                if (userCount > overCount)
                {

                    userbase.users.push_back(tempBuffer);
                    overCount++;

                }
                buffer.erase(0, 3);
                tempBuffer.ID = buffer;

            }
            else if (0 == buffer.find("created:"))
            {

                buffer.erase(0, 8);
                tempBuffer.date = buffer;

            }
            else if (0 == buffer.find("name:"))
            {

                buffer.erase(0, 5);
                tempBuffer.name = buffer;

            }
            else if (0 == buffer.find("password:"))
            {
                buffer.erase(0, 9);
                tempBuffer.password = buffer;
            }
            else if (0 == buffer.find("status:"))
            {
                buffer.erase(0,7);
                if (buffer == "active")
                    tempBuffer.active = true;
                else if (buffer == "inactive")
                    tempBuffer.active = false;
            }



        }
        if (userCount == 0)
        {
            userbase.users.push_back(tempBuffer);
        }

        inFile.close();
    }
    else    // If no userlist.txt exists, create new one from vector. This instance works, but there is only one user
    {
        cout << "NO USERS FOUND, CREATING NEW LIST.\n";
        inFile.close();

        // Determine current date
        time_t rawtime;
        struct tm * timeinfo;

        time (&rawtime );
        timeinfo = localtime ( &rawtime );
        string cdate = asctime(timeinfo);

        userstats userBuffer = {"1", cdate, "admin", "Admin1", admin, 1};
        userbase.users.push_back(userBuffer);

        ofstream outFile("userlist.txt");



        outFile << "created: " << cdate;
        outFile << "mod_date: " << cdate << "\n\n";
        outFile << "ID:" << userbase.users[0].ID << "\n";
        outFile << "created:" << userbase.users[0].date;
        outFile << "name:" << userbase.users[0].name << "\n";
        outFile << "password:"<< userbase.users[0].password << "\n";
        outFile << "security level:" << userbase.users[0].secLev << "\n";
        outFile << "status:active\n\n";


        outFile.close();
    }

    // CHECK DIR
    char ch;
    cout << "Choices are listed below\n";
    cout << "1) login\t2) Register an Account\n"
         << "q) Quit.\n";
    cout << "Select option: ";

    bool breakFlag = false;
    while (breakFlag == false && cin.get(ch))
    {
        cin.ignore();
        // Could use getch to eliminate errors instead.

        switch (ch)
        {
            case '1':   int logID;
                        logID = userbase.login();
                        if (logID)
                        {
                            logID -= 1;
                            loggedin(logID);
                        }
    ...

此外,如果我在 dbmani.h 中使用 regAcc() 注册了第二个帐户“admina”,我注意到我的用户列表看起来像这样(创建第三个帐户将覆盖第二个帐户),

created: Sun May 13 18:41:08 2012
mod_date: Sun May 13 19:08:01 2012


ID:1
created:Sun May 13 18:41:08 2012name:admin
password:Admin1
status:active

ID:2
created:Sun May 13 19:08:01 2012
name:admina
password:Admin1
security level:0
status:active

这里是源代码,如果你喜欢的话: http://www.mediafire.com/download.php?6dp6sxn952j7s37

如果有人能花一些时间帮助我,我将不胜感激,如果只是解决“.txt to vector”问题的话,因为我时间不多了,而且我真的看不到错误。我尝试查看网页,但似乎没有找到任何相关信息。

最佳答案

在不看压缩代码的情况下,我突然想到了一些事情:

1) 您正在搜索字符串 'created',但您会发现它位于文件的最开头,它不是记录的一部分,并且会给出误报

2) 在读取 .txt 文件结束时,您似乎没有将最后一条记录添加到您的记录 vector 中(除非用户总数为 0,这似乎不太可能)

3) tempBuffer 永远不会被清除,所以如果记录 4 有创建日期而记录 5 没有,记录 5 将与记录 4 的创建日期一起存储。

当找到“ID:”时,我会倾向于立即读取整个记录,所以像这样:

if (0 == buffer.find("ID:"))
{
    tempBuffer.ID = buffer.substr(3);
    if (!getline(inFile, buffer) || buffer.find("created:") != 0)
    {
        cerr << "Error reading record for ID" << tempBuffer.ID << endl;
        exit(1);
    }

    tempBuffer.date = buffer.substr(8);
    // ...etc

    userbase.users.push_back(tempBuffer);
}

希望这也有助于消除文件格式中的错误。

关于c++ - .txt 到 vector<struct> 故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10573619/

相关文章:

r - 将向量列表转换为数据框

c++ - vector 的 Push_front() 替代方案和 map 的 operator++

c++ - C++ 中的正确形式

c++ - 如何在没有 WS_EX_LAYERED 的情况下在 C++ 中制作点击窗口

c++ - 智能指针 : who owns the object?

html - 更改输入类型 ="file"上的光标类型

c++ - "while (c = getchar())"等价于 C++

c - 出现一个额外的输入

c++ - OfxEtherDream : where is getNumEtherdream()?

c++ - vector 不是 "saving values"C++