0

私は現在、学校の試験プロジェクトを仕上げています。アカウント経由でログインし、システム内の他のユーザーにメッセージを書き込むことができるユーザーデータベースを作成します。しかし、いくつかのバグがあり、今まで発見できませんでした。プログラムが最初に実行されると、ユーザー データベースが次のような .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

ベクトルからコピーされたので、これは問題なく動作します。しかし、プログラムを 2 回目に開いたときに逆のプロセスを実行する必要があり (userlist.txt を削除しない限り)、ベクトルに間違った情報が保持されているようです。説明が難しいので、ソースコードをmediafireにアップしました。合計 600 行のコードがあると思いますが、問題を確認するには、main.cpp と、dbmani.h (ベクトルがクラス内で定義されている場所) 内の関数 login() および writedb() だけが必要だと思います。 . ソース コードのすべてをダウンロードする必要がないことを願って、コードの最初の行はここにあります (ベクトルが存在する場合、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() を使用して 2 番目のアカウント「admina」を登録すると、ユーザーリストが次のようになることに気付きました (3 番目のアカウントを作成すると 2 番目のアカウントが上書きされます)。

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

必要に応じて、ソース コードを次に示します

「.txtからベクターへ」の問題だけでも、時間がなくなってエラーが本当に見えないので、誰かが私を助けてくれたらとても感謝しています。ウェブを調べてみましたが、それについては何も見つけられなかったようです。

4

1 に答える 1

1

圧縮されたコードを見なくても、いくつかのことが飛び出します。

1) 'created' という文字列を検索していますが、ファイルの先頭にあることがわかります。これはレコードの一部ではなく、誤検出を引き起こします。

2) .txt ファイルの読み取りの最後に、レコードのベクトルに最後のレコードを追加したようには見えません (ユーザーの総数が 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);
}

うまくいけば、これはファイル形式のエラーも取り除くのに役立ちます.

于 2012-05-13T17:37:10.137 に答える