c语言用户登录注册系统

改完有新问题了,输入错误密码也会显示欢迎登陆,而且文件里还是很多“烫”

#include
#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)
    {
        while(fread(&b,sizeof(Users),1,fp)==1); //读取一个用户
        {
            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;
    FILE *fp;
    printf("欢迎注册!\n");
    
    printf("请设置用户名(小于30字符):\n");
    scanf("%s",a.username);
    a.username[strlen(a.username)]='\0';
    fp=fopen("Users.txt","r");    
    while (fread(&b, sizeof(Users), 1, fp) == 1)
    {
        if (strcmp(a.username, b.username) == 0)  //如果此账号已存在,退出注册界面
        {
            printf("此用户名已存在!\n");
            fclose(fp);
            return;
        }
    }

        fclose(fp);
        fp=fopen("Users.txt","a");    // 以追加方式打开文件
        fwrite(&a,sizeof(Users),1,fp);
        printf("请设置密码(小于10字符):");
        scanf("%s",a.password);
        a.password[strlen(a.password)]='\0';
        printf("账号注册成功!\n");
        fclose(fp);
        return;    
}    

img

img

烫说明字符串没有截断,我想每一个程序员都应该知道“烫烫烫”是什么梗吧

整体修改如下,供参考:

#include<stdio.h>
#include<string.h>
#include<windows.h>
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;
    int  i = 0;
    fp = fopen("Users.txt","r");
    if (fp == NULL)                            //修改
        printf("尚未注册用户,请注册后登陆!\n");
    else{
        printf("\n欢迎登录背单词系统\n");        //修改
        printf("请输入用户名:");
        scanf("%s",a.username);
        do {                                   //修改
            fread(&b,sizeof(Users),1,fp);
            if (strcmp(a.username,b.username) == 0) break;
        } while (!feof(fp));                   //修改
        if (feof(fp))
            printf("该用户名不存在!\n");       //修改
        else{
            do {                               //修改
                printf("输入密码:");
                scanf("%s",a.password);
                if(strcmp(a.password,b.password)==0){
                    printf("\n登录背单词系统成功!\n");
                    break;
                }
                else{
                    i++;
                    if (i != 3)
                        printf("密码错误,还有%d次机会,请重新", 3 - i);
                    else {
                        printf("输入密码错误,3次机会已用完,退出登录!\n");
                        break;
                    }
                }
            } while (strcmp(a.password,b.password)!=0);//修改
        }
        fclose(fp);
    }
}
void register_()
{
    Users a,b;
    FILE *fp;
    printf("欢迎注册用户!\n");
    fp = fopen("Users.txt","r");
    if (fp == NULL){                             //修改
        printf("请设置用户名(小于30字符):\n");
        scanf("%s",a.username);
        printf("请设置密码(小于10字符):");
        scanf("%s",a.password);
    }
    else{                                       //修改
        while (1){
            printf("请设置用户名(小于30字符):\n");
            scanf("%s",a.username);
            do {
                fread(&b, sizeof(Users), 1, fp);
                if (strcmp(a.username, b.username) == 0)//如果此账号已存在
                   { printf("此用户名已存在,"); break;}
            }while (!feof(fp));
            if (feof(fp))
                break;
            else
                rewind(fp);
        }
        printf("请设置密码(小于10字符):");
        scanf("%s",a.password);
        fclose(fp);
    }
    fp = fopen("Users.txt","a+");    //修改
    fwrite(&a,sizeof(Users),1,fp);
    fclose(fp);
    printf("账号注册成功!\n");
    return;
}

在login()函数中,需要加入一个判断语句,判断用户名是否存在于文件中,如果不存在就提示用户尚未注册,并返回上一级菜单。此外,还需要修改读取一个用户信息的方式,不再使用while循环读取,而是用if语句判断是否成功读取到一个用户。修改后的代码如下:

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");
int user_exist = 0; //标记用户是否存在
while(fread(&b,sizeof(Users),1,fp)==1) //读取一个用户
{
if(strcmp(a.username,b.username)==0) //找到了对应的用户名
{
user_exist = 1; //将标记设为1
if(strcmp(a.password,b.password)==0) //密码正确
{
printf("欢迎登录!\n");
fclose(fp);
return;
}
else //密码错误
{
printf("用户名或密码错误\n");
fclose(fp);
return;
}
}
}
//文件结束,但用户不存在
if(!user_exist)
{
fclose(fp);
printf("您尚未注册,请注册后登陆!\n");

}
}

在register_()函数中,为了防止字符串越界,需要在读取用户名和密码后立即将末尾加上'\0',并且要在每次写入文件前先关闭文件。另外,为了防止以追加方式打开文件时写入错误的数据,应当先读取文件判断是否存在重名用户,只有不存在重名用户时才进行写入操作。修改后的代码如下:

void register_()
{
Users a,b;
FILE *fp;
printf("欢迎注册!\n");

printf("请设置用户名(小于30字符):\n");
scanf("%s",a.username);
a.username[strlen(a.username)]='\0';

fp=fopen("Users.txt","r");    
while (fread(&b, sizeof(Users), 1, fp) == 1)
{
    if (strcmp(a.username, b.username) == 0)  //如果此账号已存在,退出注册界面
    {
        printf("此用户名已存在!\n");
        fclose(fp);
        return;
    }
}
fclose(fp);

fp=fopen("Users.txt","a");    // 以追加方式打开文件
printf("请设置密码(小于10字符):");
scanf("%s",a.password);
a.password[strlen(a.password)]='\0';
fwrite(&a,sizeof(Users),1,fp);
printf("账号注册成功!\n");
fclose(fp);
return;    
}