【发布时间】:2016-02-01 13:09:19
【问题描述】:
我正在尝试制作一个登录表单,并且我已经输入了一个选项,可以在用户登录后修改他的电子邮件 ID。为此,我编写了以下代码。
char newmail[50];
cout<<"Enter New Email Id\n";
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 sucessfully\n";
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 FORM\n";
cout<<"Enter User name\n";
cin>>username;
cout<<"Enter Email\n";
cin>>email;
cout<<"Enter Password\n";
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 MENU\n";
cout<<"ENTER 1 FOR NEW REGISTRATION\n";
cout<<"ENTER 2 TO LOGIN\n";
cout<<"ENTER 3 FOR MEMBER LIST\n";
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 successful\n";
}
if(ch==2)
{
char uname[50];
char pass[50];
int flag=0;
cout<<"LOGIN\n";
cout<<"Enter Username and Password\n";
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 Successful\n";
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 exit\n";
cin>>i;
if(i==1)
{
char newmail[50];
cout<<"Enter New Email Id\n";
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 sucessfully\n";
break;
}
else if(i==2)
{
exit(0);
}
}
}
f.read((char*)&u, sizeof(user));
}
f.close();
if(flag==0)
{
cout<<"Wrong username or password\n";
}
}
if(ch==3)
{
cout<<"MEMBER LIST\n";
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 menu\n";
cin>>ans;
}while(ans=='y' || ans=='Y');
}
【问题讨论】:
-
您的 f.open() 调用不会破坏文件的先前内容吗?此外,代码很脆弱:如果用户输入的电子邮件地址超过 49 个字符,缓冲区将溢出并导致未定义的行为。
-
@KlitosKyriacou 请详细说明 f.open() 调用的事情。我也很清楚 49 个字符的限制。这只是一个学校项目,没什么大不了的!
-
试试这个:
std::cout << -sizeof(user) << std::endl;。你可能会感到惊讶。 (你的程序更新电子邮件不是很慢吗?我的是。) -
您打开同一个文件两次。尝试打开一次
-
ios::out |ios::ate| ios::binary丢弃文件的内容。ios::in | ios::out |ios::ate| ios::binary没有。
标签: c++ file-io file-handling