C++:无法修改文件中的某个记录

C++: Unable to modify a certain record in a file

本文关键字:记录 文件 修改 C++      更新时间:2023-10-16

我正在尝试制作登录表单,并且我已经输入了一个选项,可以在用户登录后修改用户的电子邮件ID。为此,我编写了以下代码。

char newmail[50];
                         cout<<"Enter New Email Idn";
                         cin>>newmail;
                         fstream f2;
                         f2.open("db.txt" ,  ios::out |ios::ate| ios::binary);
                         strcpy(u.email,newmail);
                         f2.seekp(pos,ios::beg);
                         cout<<f2.tellp()<<endl;
                         f2.write((char*)&u, sizeof(user));
                         f2.close();
                         cout<<"Details edited sucessfullyn";
              break;

它的问题是:我登录。选择用于修改电子邮件 ID 的选项。输入新的。没有错误,详细信息编辑成功。然后,当我去检查用户列表(也为此编写了代码,完美工作)时,所有用户都无效,即他们的数据为空,但空间仍然被占用,只有一条记录包含所有数据,是的,电子邮件 ID 被修改了。当我使用 f2.seekp(-sizeof(u),ios::cur); 专门将指针设置在当前记录上时,我无法弄清楚为什么所有数据都无效。我已经交叉检查了指针的位置,光标在其位置。整个代码是这样的:-

    #include<iostream>
#include<fstream>
#include<string.h>
#include<stdlib.h>
using namespace std;
class user
{public:
    char username[50];
    char password[50];
    char email[50];

    int reg()
    {
        cout<<"REGISTRATION FORMn";
        cout<<"Enter User namen";
        cin>>username;
        cout<<"Enter Emailn";
        cin>>email;
        cout<<"Enter Passwordn";
        cin>>password;
    }
    int putdata()
    {
        cout<<"Username   "<<username<<"         "<<"Email ID  "<<email<<endl;
    }
    char* retuser()
    {
       return username;
    }
    char* retpass()
    {
        return password;
    }
    char* retmail()
    {
        return email;
    }

};

int main()
{int a=sizeof(user);
    char ans;
    int ch;
    fstream f;
    user u;
    do
    {
        cout<<"MAIN MENUn";
        cout<<"ENTER 1 FOR NEW REGISTRATIONn";
        cout<<"ENTER 2 TO LOGINn";
        cout<<"ENTER 3 FOR MEMBER LISTn";
        cin>>ch;
        if(ch==1)
        {
           u.reg();
           f.open("db.txt", ios::app|ios::out|ios::binary);
            f.write((char*)&u, sizeof(user));
            f.close();
            cout<<"Registration successfuln";
        }
        if(ch==2)
        {
             char uname[50];
             char pass[50];
             int flag=0;
             cout<<"LOGINn";
             cout<<"Enter Username and Passwordn";
             cin>>uname>>pass;
             f.open("db.txt", ios::in | ios::binary);
             f.read((char*)&u, sizeof(user));
             while(f)
             {
                 if(strcmp(u.retuser(),uname)==0)
                 {
                     if(strcmp(u.retpass(),pass)==0)
                     {
                         flag=1;
                         cout<<"Login Successfuln";
                         cout<<"USERNAME : -"<<u.retuser()<<endl;
                         cout<<"EMAIL ID : -"<<u.retmail()<<endl;
                         int pos;
                         pos=f.tellg();
                         pos=pos-a;
                         int i;
                         cout<<"Press 1 to modify email id, 2 to exitn";
                         cin>>i;
                         if(i==1)
                         {
                             char newmail[50];
                             cout<<"Enter New Email Idn";
                             cin>>newmail;
                             fstream f2;
                             f2.open("db.txt" ,  ios::out |ios::ate| ios::binary);
                             strcpy(u.email,newmail);
                             f2.seekp(pos,ios::beg);
                             cout<<f2.tellp()<<endl;
                             f2.write((char*)&u, sizeof(user));
                             f2.close();
                             cout<<"Details edited sucessfullyn";
                             break;
                         }
                         else if(i==2)
                         {
                             exit(0);
                         }
                     }
                 }
                 f.read((char*)&u, sizeof(user));
             }
             f.close();
              if(flag==0)
            {
                cout<<"Wrong username or passwordn";
            }
        }
        if(ch==3)
        {
            cout<<"MEMBER LISTn";
            f.open("db.txt", ios::in | ios::binary );
            f.read((char*)&u, sizeof(user));
            while(f)
            {
                u.putdata();
                f.read((char*)&u, sizeof(u));
            }
            f.close();
        }
        cout<<"Enter y to go to main menun";
        cin>>ans;
    }while(ans=='y' || ans=='Y');
}

为了能够在正确的位置修改文件,您应该打开文件(一次)进行输入和输出。我将只向您展示管理邮件地址更改的代码部分,即使您应该改进代码并在许多其他部分添加一些用户输入检查。

    if(ch==2) // I'd prefer a switch() here
    {
        char uname[50];
        char pass[50];
        int flag=0;
        cout << "LOGINn";
        cout << "Enter Username and Passwordn";
        cin >> uname >> pass;
        fstream f("db.txt", ios::in | ios::out| ios::binary);
        if ( f.bad() ) {
            cout << "Error, unable to open users database file.";
            exit(1);
        }
        // check the position BEFORE reading the user
        int pos = f.tellg();
        while( f.read((char*)&u, sizeof(user)) ) {
            if( strcmp(u.retuser(),uname) == 0  
                    &&  strcmp(u.retpass(),pass) == 0 ) {
                flag = 1;
                cout << "Login Successfuln";
                cout << "USERNAME : -"<<u.retuser()<<endl;
                cout << "EMAIL ID : -"<<u.retmail()<<endl;
                int i;
                cout << "Press 1 to modify email id, 2 to exitn";
                cin >> i;
                if( i == 1 ) {
                    char newmail[50];
                    cout << "Enter New Email Idn";
                    cin >> newmail;
                    strcpy(u.email,newmail);
                    f.seekp(pos,ios::beg);
                    f.write((char*)&u, sizeof(user));
                    cout << "Details edited sucessfullyn";
                    break;
                } else if ( i == 2 ) {
                    exit(0);
                }
            }
            pos=f.tellg();
        }
        f.close();
        if ( flag == 0 ) {
            cout << "Wrong username or passwordn";
        }
    }