【自制系列】自制文本编辑器(控制台版本) 第四篇
我们继续开始我们的文本编辑器的改进。之前一直有一个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行了,完。