为什么我这个注册登录系统运行的时候,注册之后登陆,显示用户名密码错误,在资源文件里是有存上的,但是有很多“烫”
#include
#include
void login();
void register_();
typedef struct
{
char username[30];
char password[10];
int score;
int days;
}Users;
typedef struct
{
char English[20];
char property[10];
char Chinese[50];
}Word;
int main()
{
int n;
while(1)
{
printf("欢迎使用背单词系统\n\n"); //首页界面
printf("1:登录\n");
printf("2:注册\n");
printf("0:退出\n");
printf("请选择您想进行的操作并输入编号:"); //功能选择
scanf("%d",&n);
switch(n) //判断
{
case 1:
login(); break;
case 2:
register_();break;
case 0:exit(1);break;
default:
printf("您输入的操作编号有误,请重新输入!\n");
}
}
}
void login() //登录
{
Users a,b; //定义结构体The_users别名
FILE *fp;
printf("欢迎使用背单词系统\n");
printf("请输入用户名:");
scanf("%s",&a.username);
printf("请输入密码:");
scanf("%s",&a.password);
fp = fopen("Users.txt","r");
while(1)
{
fread(&b,sizeof(Users),1,fp); //读取一个用户
if(strcmp(a.username,b.username)==0||(!feof(fp)))
break;
else
{
if(!feof(fp))
{
fread(&b,sizeof(Users),1,fp);
}
else
{
fclose(fp);
printf("您尚未注册,请注册后登陆!\n");
}
}
}
fclose(fp);
if(strcmp(a.password,b.password)==0)
{
printf("欢迎登录!\n");
}
else
{
printf("用户名或密码错误\n");
}
}
void register_()
{
Users a,b;
int i=0;
FILE *fp;
char password_[10];
printf("欢迎注册!\n");
fp=fopen("Users.txt","r");
fread(&b,sizeof(Users),1,fp); //读入一个用户信息
printf("请设置用户名:\n");
scanf("%s",&a.username);
a.username[i]='\0';
while (1)
{
if (strcmp(a.username,b.username)) //如果注册账号不存在
{
if (!feof(fp)) //如果未到文件尾
{
fread(&b,sizeof(Users),1,fp); //继续读入下一个用户信息
}
else
{
break;
}
}
else //如果此账号已存在,退出注册界面
{
printf("此用户名已存在!\n");
fclose(fp);
return;
}
}
fp=fopen("Users.txt","a"); // 以追加方式打开文件
fwrite(&a,sizeof(Users),1,fp);
printf("请设置密码:");
scanf("%s",&a.password);
a.password[i]='\0';
printf("账号注册成功!\n");
fclose(fp);
return;
}
引用new bing部分回答作答:
您好!根据您提供的代码,出现这种情况的原因可能有以下几点:
1 密码输入的长度超出了定义的数组长度,导致内存越界。在代码中,用户密码的数组长度定义为10,如果用户输入的密码长度超出了10,就会出现这种情况。
2 读取文件时,可能存在乱码。您提到资源文件中有很多“烫”,这可能是因为您在写入文件时使用了二进制方式,而在读取文件时使用了文本方式。建议在打开文件时,同时指定打开方式,例如在打开文件时使用二进制方式打开文件:
fp = fopen("Users.txt","rb");
3 在输入字符串时,没有正确地添加字符串结束符'\0'。例如在注册函数中,您输入的用户名和密码,最后并没有添加字符串结束符'\0',导致字符串没有正确结束,可能会影响后续的判断。建议在输入字符串时,添加字符串结束符'\0',例如:
scanf("%s", a.username);
a.username[strlen(a.username)] = '\0'; // 添加字符串结束符'\0'
4 在 register_() 函数中,你使用 fread() 函数读取一个用户信息,但没有进行feof()判断。如果文件读取到末尾,将无法得到正确的结果。
5 在 register_() 函数中,设置密码的代码里,应该是i++,而不是i='\0',因为后者会将字符串的第一个字符置为 '\0'。
6 在 login() 函数中,当用户名和密码都匹配成功时,应该结束循环并返回到主菜单,否则会陷入死循环。
问题1:scanf用法不对,例如 scanf("%s", &a.username) 应为 scanf("%s", a.username)
问题2:注册时或登录时,没判断文件不存在的情况
问题3:注册时,文件打开了还没关闭,又重新打开了
问题4:注册时,密码还没设置呢,就保存文件了
问题5:a.username[i]='\0'; 和 a.password[i]='\0 错误,需要删掉
问题6:登录条件中的||(!feof(fp)) 错误,需要删掉
问题7:登录函数的未注册分支中,应加上renturn
问题8:fopen的参数应加上b,例如 ab rb
问题9:所有fopen/fread/fwrite应判断成功失败
问题10:为避免文件存入脏数据,应用对结构体数据清0,memset(&用户结构体, 0, sizeof(Users))
C语言中默认数是有符号的,比如1234或者0x1234,都会被默认为是有符号的,而如果你想声明一个无符号数,你需要加上后缀“U”或者“u”。例如1234u或者0x1234U。
C语言是允许有符号数和无符号数相互转换的,遵从的规则就是我们刚刚介绍过得T2U和U2T的规则。
但是C语言中如果有符号数和无符号数进行运算时,系统会默认将有符号数转换成无符号数来进行运算。因此,有些时候有些运算的结果会和我们一般的预期不一致。例如,在32位机器上面,short类型的-1<0答案肯定是true,但是如果-1<0U,这时答案就是false了。因为会将有符号数-1转换为无符号数65535和无符号数0进行比较,结果会是false。