天天看点

【自制系列】自制文本编辑器(控制台版本) 第四篇

我们继续开始我们的文本编辑器的改进。之前一直有一个bug,忘记说了,就是下面,print没有用户检测

【自制系列】自制文本编辑器(控制台版本) 第四篇
然后,我们发现了一个bug。假设userinfo.txt如下:

//userinfo.txt
1
admin 114514      

 默认用户admin,密码114514(这数字...)

>login admin 114514
>open secret.txt
>line secret
>close
>logoff
>      

我们使用如上的指令进行打开一个secret.txt,放入文本并保存。

然后,如果我们没有admin的密码,想要打开这个txt,我们可以这样干:

>adduser admin 0
>open secret.txt
>print
secret
>close
>      

使用相同的用户名,就可以打开其他用户的文件!此时userinfo如下:

2
admin 114514
admin 0      

因此,我们需要在adduser的时候,进行判断。另外,这里笔者在读代码的时候,发现size变量和user_ptr重复了,这里统一了user_ptr。

直接把完整代码放上来:

1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 
  5 //全局变量定义区 
  6 struct USER{
  7     char name[100];
  8     int password;
  9 }user[10000];
 10 char s[100];
 11 struct USER curr_user;
 12 int flag=0;//如果当前有用户正在运行标记为1,否则为0 
 13 char curr_file[100];
 14 struct FILE *userfile;
 15 struct FILE *read;
 16 char openfilename[100];
 17 struct FILE* userinfo;//读入用户信息 
 18 
 19 int user_ptr=0;//当前最大的用户下标 
 20 
 21 
 22 //函数定义区 
 23 int check_user(struct USER u){//确认用户名和密码 
 24     for(int i=0;i<=user_ptr;i++){
 25         if((strcmp(u.name,user[i].name)==0) && u.password==user[i].password)return 1;
 26     }
 27     return 0;
 28 }
 29 void open_file(const char *username,const char *filename){
 30     char s[100];
 31     sprintf(s,"%s-%s",username,filename);//文件的最前面要加上用户名的标记 
 32     userfile=fopen(s,"a+");//打开文件,原本内容保留,因此用a+ 
 33     read=fopen(s,"r");
 34     strcpy(openfilename,s);
 35 }
 36 void write_userinfo(void){
 37     userinfo=fopen("userinfo.txt","w");
 38     fprintf(userinfo,"%d\n",user_ptr+1);
 39     for(int i=0;i<=user_ptr;i++){
 40         fprintf(userinfo,"%s %d\n",user[i].name,user[i].password);
 41     }
 42     fclose(userinfo);
 43 }
 44 int check_user_2(struct USER u){
 45     for(int i=0;i<user_ptr;i++){
 46         if((strcmp(u.name,user[i].name)==0))return 1;
 47     }
 48     return 0;
 49 }
 50 
 51 
 52 //主程序 
 53 int main(void){
 54     userinfo=fopen("userinfo.txt","r");
 55     int i=0;
 56     fscanf(userinfo,"%d",&user_ptr);
 57     for(int i=0;i<user_ptr;i++){
 58         fscanf(userinfo,"%s %d",user[i].name,&user[i].password);
 59         //printf("%s %d\n",user[i].name,user[i].password);
 60     }
 61     fclose(userinfo);
 62     
 63     for(;;){
 64         putchar('>');
 65         scanf("%s",&s);
 66         if(strcmp(s,"login")==0){
 67             scanf("%s %d",curr_user.name,&curr_user.password);
 68             int i=check_user(curr_user);
 69             if(!i)printf("密码错误或用户名错误。\n");
 70             else{
 71                 flag=1;
 72             }
 73         }
 74         else if(strcmp(s,"logoff")==0){
 75             flag=0;
 76         }
 77         else if(strcmp(s,"getuser")==0){
 78             if(flag==0)printf("无用户登录\n");
 79             else printf("%s\n",curr_user.name);
 80         }
 81         else if(strcmp(s,"open")==0){
 82             scanf("%s",curr_file);
 83             if(!flag)printf("还没有登录\n");
 84             else open_file(curr_user.name,curr_file);
 85         }
 86         else if(strcmp(s,"line")==0){
 87             char st[100];
 88             scanf("%s",st);
 89             if(!flag)printf("还没有登录\n");
 90             else fprintf(userfile,"%s\n",st);//新加入一行 
 91         }
 92         else if(strcmp(s,"close")==0){
 93             if(!flag)printf("还没有登录\n");
 94             else fclose(userfile);
 95         }
 96         else if(strcmp(s,"clear")==0){
 97             system("cls");
 98         }
 99         else if(strcmp(s,"print")==0){
100             if(!flag)printf("还没有登录\n");
101             else{
102                 read=fopen(openfilename,"r");
103                 int temp;//EOF为负数,需要用int存储 
104                 while((temp=fgetc(read))!=EOF)putchar(temp);
105                 fclose(read);
106             }
107         }
108         else if(strcmp(s,"adduser")==0){
109             ++user_ptr;
110             scanf("%s %d",user[user_ptr].name,&user[user_ptr].password);
111             int i=check_user_2(user[user_ptr]);
112             if(i)printf("用户已经存在\n");
113             else{
114                 curr_user=user[user_ptr];
115                 flag=1;
116                 write_userinfo();
117             }
118         }
119         else{
120             printf("%s不是可执行的指令。\n",s);
121         }
122     }
123 }      

短短几天时间,已经123行了,完。