软件开发与创新 第一周作业
一、来源
本次用于作业的源程序来自的朋友的c语言大作业
二、运行环境与运行截图
运行环境:Win11 DevC++
代码:
点击查看代码
# include "stdio.h"
# include "stdlib.h"
# include "string.h"
# define size 100
typedef struct
{
long booknumber;
char bookname[15];
char auther[20];
char press[20];
float price;
int nownum;
}book;
typedef struct
{
long cardnumber;
char name[20];
char sex[10];
long tel;
char clas[20];
char condition[20];
}Member;
void Bookfound();
void Bookdel();
void Bookadd();
void Booklook();
void Booksearch();
void Memberadd();
void Memberchange();
void Bookborrow();
void Bookreturn();
//***********************************************//
int login(char password[])
{
static char key[10]="123";
if(strcmp(password,key)==0)
return 1;
else
return 0;
}
int main()
{
int choice;
do
{
printf("|==========================================|\n");
printf("| 欢迎使用图书管理系统 |\n");
printf("|******************************************|\n");
printf("| 图书管理 |\n");
printf("|==========================================|\n");
printf("| 1,创建图书信息 |\n");
printf("| 2,删除图书 |\n");
printf("| 3,增添图书 |\n");
printf("| 4,按名称查询图书 |\n");
printf("| 5,按作者查询图书 |\n");
printf("| 6,创建读者信息 |\n");
printf("| 7,修改读者信息 |\n");
printf("|==========================================|\n");
printf("| 借书和还书管理 |\n");
printf("|******************************************|\n");
printf("| 8,借书 |\n");
printf("| 9,还书 |\n");
printf("| 0,退出系统 |\n");
printf("============================================\n");
printf("\n您好!请输您的选择(1,2,3,4,5,6,7,8,9,0):\n");
scanf("%d",&choice);
switch(choice)
{
case 1:Bookfound();break;
case 2:Bookdel();break;
case 3:Bookadd();break;
case 4:Booklook();break;
case 5:Booksearch();break;
case 6: Memberadd();break;
case 7: Memberchange();break;
case 8:Bookborrow();break;
case 9:Bookreturn();break;
case 0:exit(0);break;
}
}while(1);
}
//************************1输入图书信息***********************//
void Bookfound()
{
FILE *fp=NULL;
book a;
char filename[20]="";
int h=1;
printf("\n为了存储图书信息请输入一个文件名.\n");
scanf("%s",filename);
if((fp=fopen(filename,"wb+"))==NULL)
{
printf("\ncan not open this file");
return;
}
printf("请输入书的信息\n");
printf("如过你输入的书号为0则表示输入结束了\n");
while(h<=size)
{
printf("请输入书号:\n");
scanf("%ld",&a.booknumber);
if(a.booknumber==0)
break;
printf("请输入书名:\n");
scanf("%s",a.bookname);
printf("请输入作者:\n");
scanf("%s",a.auther);
printf("请输入出版社:\n");
scanf("%s",a.press );
printf("请输入价格:\n");
scanf("%f",&a.price );
printf("请输入当前的数量:\n");
scanf("%d",&a.nownum);
printf("==================================\n");
if(fwrite(&a,sizeof(book),1,fp)!=1)
{
printf("write file %s fail",filename);
return;
}
h++;
}
fclose(fp);
printf("你输入书的信息已经成功存储在文件里了\n");
printf("输入文件的内容如下:\n");
if((fp=fopen(filename,"rb+"))==NULL)
{
printf("can not open the file.\n");
return;
}
printf("\n书号\t书名\t作者\t出版社\t价格\t数量\n");
while(fread(&a,sizeof(book),1,fp)!=0)
{
printf("\n%ld\t%s\t%s\t%s\t%f\t%d\n",a.booknumber,a.bookname,a.auther,a.press,a.price ,a.nownum );
}
fclose(fp);
}
//************************删除图书信息***********************//
void Bookdel()
{
int i;
long No;
book a;
book s[size];
int R;
char filename[30];
FILE *fp;
printf("\n请输入存放书的文件名.\n");
scanf("%s",filename);
if((fp=fopen(filename,"rb"))==NULL)
{
printf("\ncan not open this file");
return;
}
printf("请输入你要删除的书号:\n");
scanf("%ld",&No);
printf("你要删除的书号为:%ld\n",No);
R=0;
while(fread(&a,sizeof(book),1,fp)!=0)
{
if(a.booknumber!=No)
{
s[R].booknumber=a.booknumber;
strcpy(s[R].bookname,a.bookname);
strcpy(s[R].auther,a.auther);
strcpy(s[R].press,a.press);
s[R].price =a.price;
s[R].nownum =a.nownum ;
R++;
}
}
fclose(fp);
if((fp=fopen(filename,"wb+"))==NULL)
{
printf("\ncan not open this file");
return;
}
for(i=0;i<R;i++)
{
if(fwrite(&s[i],sizeof(book),1,fp)!=1)
{
printf("write file %s fail",filename);
return;
}
}
fclose(fp);
if((fp=fopen(filename,"rb"))==NULL)
{
printf("\ncan not open this file");
return;
}
printf("删除以后文件里的内容如下:\n");
printf("\n书号r\t书名\t作者\t出版社\t价格\t数量\n");
while(fread(&a,sizeof(book),1,fp)!=0)
{
if(a.booknumber!=0)
printf("\n%ld\t%s\t%s\t%s\t%f\t%d\n",a.booknumber,a.bookname,a.auther,a.press,a.price,a.nownum);
}
fclose(fp);
}
//************************增加图书信息***********************//
void Bookadd()
{
FILE *fp=NULL;
book a;
char filename[30];
int h=1;
printf("\n请输入存放书的文件名.\n");
scanf("%s",filename);
if((fp=fopen(filename,"a+"))==NULL)
{
printf("\ncan not open this file");
return;
}
printf("请输入你要添加的书的信息\n");
printf("如果你输入的书号为0,这表示输入结束\n");
while(h<=size)
{
printf("请输入书号\n");
scanf("%ld",&a.booknumber);
if(a.booknumber==0)
break;
printf("请输入书名:\n");
scanf("%s",a.bookname);
printf("请输入作者:\n");
scanf("%s",a.auther);
printf("请输入出版社:\n");
scanf("%s",a.press);
printf("请输入价格\n");
scanf("%f",&a.price);
printf("请输入当前的数量:\n");
scanf("%d",&a.nownum);
printf("==================================\n");
if(fwrite(&a,sizeof(book),1,fp)!=1)
{
printf("write file %s fail",filename);
return;
}
h++;
}
if(h>size)
printf("\n对不起,您的输入超量了");
fclose(fp);
printf("您输入的内容成功存储在文件中\n");
printf("内容如下:\n");
if((fp=fopen(filename,"rb"))==NULL)
{
printf("cannot open the file\n");
return;
}
printf("\n书号\t书名\t作者\t出版社\t价格\t数量\n");
while(fread(&a,sizeof(book),1,fp)!=0)
{
printf("\n%ld\t%s\t%s\t%s\t%f\t%d\n",a.booknumber,a.bookname,a.auther,a.press ,a.price,a.nownum );
}
fclose(fp);
}
//***********************按书名查询图书信息************************//
void Booklook()
{
FILE *fp;
book a;
char shum[20];
int result=0;
char filename[20];
printf("请输入您要查询的书名:\n");
scanf("%s",shum);
result=0;
printf("\n请输入存储书的文件名.\n");
scanf("%s",filename);
if((fp=fopen(filename,"rb"))==NULL)
{
printf("\ncan not open this file.");
return;
}
while(feof(fp)==0)
{
{if(fread(&a,sizeof(book),1,fp)!=0)
if(strcmp(shum,a.bookname)==0)
{
printf(":\n您要查找的图书信息如下:\n");
printf("书名:%s\n",a.bookname);
printf("书号:%ld\n",a.booknumber);
printf("价格:%f\n",a.price);
printf("作者:%s\n",a.auther);
printf("出版社:%s\n",a.press);
printf("当前数量:%d\n",a.nownum);
result=1;
}
}
}
fclose(fp);
if(result==0)
{
printf("对不起没有你要找的书");
}
}
//***********************按作者查询图书信息************************//
void Booksearch()
{
FILE *fp;
book a;
char zuoz[20];
int result=0;
char filename[20];
printf("请输入您要查询图书的作者:\n");
scanf("%s",zuoz);
result=0;
printf("\n请输入存储书的文件名.\n");
scanf("%s",filename);
if((fp=fopen(filename,"rb"))==NULL)
{
printf("\ncan not open this file.");
return;
}
while(feof(fp)==0)
{
{if(fread(&a,sizeof(book),1,fp)!=0)
if(strcmp(zuoz,a.bookname)==0)
{
printf(":\nnin要查找的图书信息如下:\n");
printf("书名:%s\n",a.bookname);
printf("书号:%ld\n",a.booknumber);
printf("价格:%f\n",a.price);
printf("作者:%s\n",a.auther);
printf("出版社:%s\n",a.press);
printf("当前数量:%d\n",a.nownum);
result=1;
}
}
}
fclose(fp);
if(result==0)
{
printf("对不起没有你要找的书");
}
}
//************************创建读者信息************************//
void Memberadd()
{
FILE *fp=NULL;
Member a;
char Datafile[30]="";
int count=1;
printf("\n请输入存储读者的文件名\n");
scanf("%s",Datafile);
if((fp=fopen(Datafile,"a+"))==NULL)
{
printf("\ncan not open this file");
return;
}
printf("请输入读者的信息\n");
printf("\n如果输入的卡号为0表示输入结束\n");
while(count<=size)
{
printf("请输入卡号:\n");
scanf("%ld",&a.cardnumber);
if(a.cardnumber==0)
break;
printf("请输入名字:\n");
scanf("%s",a.name);
printf("请输入性别:\n");
scanf("%s",a.sex);
printf("请输入手机号码:\n");
scanf("%ld",&a.tel);
printf("请输入班级:\n");
scanf("%s",a.clas);
printf("请输入借书状态:\n");
scanf("%s",a.condition );
printf("----------------------------------\n");
if(fwrite(&a,sizeof(Member),1,fp)!=1)
{
printf("write file %s fail",Datafile);
return;
}
count++;
}
if(count>size)
printf("\n对不起,您输入的读者数量超量\n");
fclose(fp);
printf("您增添的读者信息已经成功存储在会员文件中\n");
printf("增添后的内容如下:\n");
if((fp=fopen(Datafile,"rb"))==NULL)
{
printf("cannot open the file\n");
return;
}
printf("\n卡号\t姓名\t性别\t手机号码\t班级\t借书状态\n");
while(fread(&a,sizeof(Member),1,fp)!=0)
{
printf("\n%ld\t%s\t%s\t%ld\t%s\t%s\n",a.cardnumber,a.name,a.sex,a.tel,a.clas,a.condition);
}
fclose(fp);
}
//************************读者信息修改*****************************//
void Memberchange()
{
FILE *fp;
long num;
long cardnumber;
char name[20];
char sex[10];
long tel;
char clas[20];
char condition[20];
Member a;
Member s[size];
int R,i;
char filename[30];
printf("\n请输入存储读者的文件名\n");
scanf("%s",filename);
if((fp=fopen(filename,"rb"))==NULL)
{
printf("\nopen file %s fail",filename);
return;
}
printf("请输入你要修改的读者的卡号:\n");
scanf("%ld",&num);
cardnumber=num;
printf("请输入名字:\n");
scanf("%s",name);
printf("请输入性别:\n");
scanf("%s",sex );
printf("请输入现在的手机号码:\n");
scanf("%ld",&tel);
printf("请输入现在的班级:\n");
scanf("%s",clas);
printf("请输入借书状态:\n");
scanf("%s",condition);
R=0;
while(fread(&a,sizeof(Member),1,fp)!=0)
{
if(a.cardnumber!=num)
{
s[R].cardnumber=a.cardnumber;
strcpy(s[R].name,a.name);
strcpy(s[R].sex,a.sex);
strcpy(s[R].clas,a.clas);
strcpy(s[R].condition,a.condition);
s[R].tel=a.tel;
R++;
}
else
{
s[R].cardnumber=cardnumber;
strcpy(s[R].name,name);
strcpy(s[R].sex,sex);
strcpy(s[R].clas,clas);
strcpy(s[R].condition,a.condition);
s[R].tel=tel;
R++;
}
}
fclose(fp);
if((fp=fopen(filename,"wb+"))==NULL)
{
printf("cannot open the file\n");
return;
}
for(i=0;i<R;i++)
{
if(fwrite(&s[i],sizeof(Member),1,fp)!=1)
{
printf("\nopen the file %s fail",filename);
return;
}
}
fclose(fp);
printf("你修改读者内容信息已经成功存储在文件中\n");
printf("修改后的内容如下:\n");
if((fp=fopen(filename,"rb"))==NULL)
{
printf("can not open the file\n");
return;
}
printf("\n卡号\t姓名\t性别\t手机号码\t班级\t借书状态\n");
while(fread(&a,sizeof(Member),1,fp)!=0)
{
if(a.cardnumber!=0)
printf("\n%ld\t%s\t%s\t%ld\t%s\t%s\n",a.cardnumber,a.name,a.sex,a.tel,a.clas,a.condition);
}
fclose(fp);
}
//***********************借书***********************//
void Bookborrow()
{
FILE *fp;
book a;
Member b;
int mflag=0,flag=0;
char bookname[20],membername[20];
char filename[20];
printf("请输入名字:\n");
scanf("%s",membername);
printf("\n请输入存储读者的文件名:");
scanf("%s",filename);
if((fp=fopen(filename,"rb"))==NULL)
{
printf("cannot open the file\n");
return;
}
while(feof(fp)==0)
{
if(fread(&b,sizeof(Member),1,fp)!=0)
{
if(strcmp(membername,b.name)==0)
{
mflag=1;
break;
}
}
}
fclose(fp);
if(mflag==1)
{
printf("你可以借书\n");
printf("请输入你要借的书名:\n");
scanf("%s",bookname);
printf("请输入存储图书的文件名:\n");
scanf("%s",filename);
if((fp=fopen(filename,"rb"))==NULL)
{
printf("cannot open file\n");
return;
}
while(feof(fp)==0)
{
if(fread(&a,sizeof(book),1,fp)!=0)
{
if(strcmp(bookname,a.bookname)==0)
{
printf("这本书存在\n");
printf("恭喜你你借书成功了\n");
flag=1;
}
}
}
if(flag==0)
{
printf("对不起,这本书被别人借走了\n");
printf("借书失败了\n");
}
if(flag==1)
{
printf("请修该图书和读者信息,把该书的信息添加到图书信息文件中,把读者的状态改为已借书状态\n");
printf("请去选择相应的功能进行修改\n");
}
fclose(fp);
}
}
//************************还书************************//
void Bookreturn()
{
FILE *fp;
book a;
Member b;
int mflag=0,flag=0;
char bookname[20],membername[20];
char filename[20];
printf("请输入名字:\n");
scanf("%s",membername);
printf("\n请输入存储的文件名:");
scanf("%s",filename);
if((fp=fopen(filename,"rb"))==NULL)
{
printf("cannot open the file\n");
return;
}
while(feof(fp)==0)
{
if(fread(&b,sizeof(Member),1,fp)!=0)
{
if(strcmp(membername,b.name)==0)
{
mflag=1;
break;
}
}
}
if(mflag==0)
{
printf("别忽悠人!你不是读者,你不可以还书!\n");
}
if(mflag==1)
{
printf("您可以还书!\n");
fclose(fp);
printf("请输入要还的书名:\n");
scanf("%s",bookname);
printf("请输入存储图书的文件名:\n");
scanf("%s",filename);
if((fp=fopen(filename,"rb"))==NULL)
{
printf("cannot open file\n");
return;
}
while(feof(fp)==0)
{
if(fread(&a,sizeof(book),1,fp)!=0)
{
if(strcmp(bookname,a.bookname)==0)
{
printf("恭喜您,还书成功!\n");
flag=1;
}
}
}
if(flag==0)
{
printf("对不起,您还错了。这本书不是我们图书馆的!\n");
printf("对不起,还书失败\n");
flag=0;
}
if(flag==1)
{
printf("请修该图书和读者信息,把该书的信息添加到图书信息文件中,把读者的状态改为已换书状态\n");
printf("请选择相应的功能进行修改\n");
}
fclose(fp);
}
}
抱歉,截图放上来是一串代码(如上),请原谅我用百度网盘呈现所有截图
链接:https://pan.baidu.com/s/19hViU-XRZYaVvZ47RhWk8A
提取码:shou
--来自百度网盘超级会员V3的分享
三、主要问题列表
这段代码实现了一个基本的图书管理系统,包含的功能有创建、删除、添加图书信息,查询图书(按名称或作者),创建和修改读者信息,以及借书和还书管理。这个系统使用C语言编写,通过控制台输入输出与用户交互,数据存储使用文件系统。
-
代码重复:
多个函数中存在重复的代码块,比如文件的打开和关闭操作,以及读写文件时的错误处理。这些重复的代码可以被封装成单独的函数,以减少代码重复,提高代码复用性和可维护性。 -
安全性:
使用scanf函数接收输入时,存在缓冲区溢出的风险。可以使用fgets和sscanf组合来代替scanf,以提高输入的安全性。
文件操作时,如果文件不存在或无法打开,程序会直接返回,但在一些情况下,可能需要更加详细的错误处理,比如提示用户错误信息或者重试。 -
数据结构选择:当前的实现中,所有的数据操作都是直接对文件进行,这在数据量较小的时候是可行的,但随着数据量的增长,直接操作文件的效率会变得很低。可以考虑使用数据库来管理图书和读者的信息,这样可以提高数据操作的效率,同时也便于实现更复杂的查询和管理功能。
-
界面和用户体验:
当前的用户界面完全基于控制台文本,用户体验较为基础。考虑使用图形用户界面(GUI)库,如GTK或Qt,来构建更友好的用户界面。 -
功能拓展和模块化:
代码中的功能集中在一个大文件中,建议按照功能模块化设计,分离成多个文件,如图书管理模块、读者管理模块等,这样可以提高代码的可读性和可维护性。
可以考虑添加更多功能,比如登录系统,统计报表、过期未还提醒等,来丰富系统的功能。 -
硬编码:
一些字符串和数字直接硬编码在代码中,如文件名和密码。建议将这些硬编码的部分提取成配置文件或者定义成常量,以便于修改和管理。 -
错误处理:
当前的错误处理较为简单,大多数情况下仅仅是打印一条错误信息然后返回。可以考虑引入更详细的错误处理机制,比如错误日志记录、异常处理等,以便于问题的诊断和解决。 -
性能优化:
在处理大量数据时,当前的文件操作可能会成为瓶颈。除了考虑使用数据库外,还可以优化数据结构和算法,比如在内存中维护一份数据的索引,减少对文件的直接读写次数。
在以上问题中,我主要针对功能拓展做了一些改善,设计了一个新的登录系统与图书管理系统绑定,以求达到更好的用户体验,以及节省管理员的监管成本
四、代码更新部分
点击查看代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
typedef struct The_users { //typedef 可以定义结构体别名
char name[11]; //账号
char pwd[20]; //密码
char phone[11]; //手机号
} Users; //该结构体别名
void Options(int); //菜单导航
void Registers(); //注册模块
void Login(); //登录模块
void Reback(); //密码找回模
int i = 0,flag = 1,menu = 0;
int main() {
printf("\n\t\t\t++++++++++++++++++++++++\n\t\t\t+ 欢迎使用XX登录系统 +\n\t\t\t++++++++++++++++++++++++\n");
// system ("color 1F"); //程序面板颜色
while (flag) {
do {
printf("\n ******************菜单栏*****************\n");
printf("\t\t*\t ①登录 *\n");
printf("\t\t*\t ②没有账号?去注册 *\n");
printf("\t\t*\t ③忘记密码?去找回 *\n");
printf("\t\t*\t ④退出系统\t\t*\n");
printf(" *****************************************\n");
printf("\n");
printf("\t\t请输入选项:[\t]\b\b\b");
scanf("%d", &menu);
} while (menu>5 || menu<1);
Options(menu);
}
}
/*
通过Option函数
接收代表功能对应的数字
来调用其他功能函数
*/
void Options(int option) {
switch (option) {
case 1:
Login();
break;
case 2:
Registers();
break;
case 3:
Reback();
break;
case 4:
printf("\n\t\t谢谢使用(^V^)!\n");
flag=0; //flag置0,结束主函数循环(也可以不要此句)
exit(0);
}
}
/*
注册账号模块
*/
void Registers() {
system("cls");
Users a,b; //定义两个临时用结构体变量
FILE *fp;
char temp_pwd[20];
int count = 0;
printf("\n\t\t欢迎来到注册界面!\n");
Sleep(500);
fp = fopen("Users.txt","r");
fread(&b, sizeof(Users), 1, fp); //读入一个用户信息,用于在下面查找注册的账号名是否存在
printf("\n\t\t请设置账号:[ \t\t ]\b\b\b\b\b\b\b\b\b\b\b\b\b");
scanf("%s",&a.name);
while (1) {
if (strcmp(a.name, b.name)) { //如果注册账号不存在
if (!feof(fp)) { //如果未到文件尾
fread(&b, sizeof(Users), 1, fp); //继续读入下一个用户信息
}
else {
break; //检查完毕,跳出
}
}
else { //如果此账号已存在,退出
printf("\t\t此用户名已存在!请重新注册!\n");
Sleep(1000);
fclose(fp);
return;
}
}
printf("\t\t请输入您的手机号:[ \t\t ]\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
scanf("%s",&a.phone);
int time = 2;
do {
printf("\t\t请设置密码:[ \t\t ]\b\b\b\b\b\b\b\b\b\b\b\b\b");
i = 0;
/*
以下代码段用于将输入的明文替换为'*'
起到保护作用,但仍存一点bug
*/
do {
a.pwd[i]=getch();
if(a.pwd[i]=='\r')
break;
if(a.pwd[i]=='\b') { //如果退格(删除键)
if(i==0) { //依旧可以让输入的内容
printf("\a"); //正确保存到密码中
continue;
}
i=i-1;
printf("\b");
}
else {
i=i+1;
printf("*"); //但已经打印出的'*'是不能消除的,此程序bug
}
} while(a.pwd[i]!='\n' && i<20); //当接收到回车符或者密码长度已够时完成密码接收
a.pwd[i]='\0';
printf("\n");
printf("\t\t请确认密码:[ \t\t ]\b\b\b\b\b\b\b\b\b\b\b\b\b");
/*
再接收一次密码
用于验证,防止用户设置密码出错
*/
i= 0;
do {
temp_pwd[i]=getch();
if(temp_pwd[i]=='\r')
break;
if(temp_pwd[i]=='\b') {
if(i==0) {
printf("\a");
continue;
}
i=i-1;
printf("\b");
}
else {
i=i+1;
printf("*");
}
} while(temp_pwd[i]!='\n' && i<20);
temp_pwd[i]='\0';
printf("\n");
if(!strcmp(a.pwd,temp_pwd)) { //如果两次输入的密码相同就可以注册了
fp = fopen("Users.txt","a"); // a-向文件尾部追加写入
fwrite(&a, sizeof(Users), 1, fp);
printf("\t\t账号注册成功!\n");
fclose(fp);
return;
}
else {
if (time!=0) {
printf("\n\t\t两次输入的密码不相同!\t请重新输入(剩余%d次机会)\n",time);
time--;
continue; //如果本次密码匹配不相同跳出,进入下一次输入
}
else {
printf("\n\t\t多次输入错误,即将退出!");
Sleep(1500);
return ;
}
}
} while(time >= 0);
}
/*
登录模块
*/
void Login() {
system("cls");
Users a,b; //定义结构体The_users别名
FILE *fp;
printf("\t\t\n欢迎来到登录界面!\n\n");
printf("\t\t请输入账号:[ \t\t ]\b\b\b\b\b\b\b\b\b\b\b\b\b");
scanf("%s",&a.name);
printf("\t\t请输入密码:[ \t\t ]\b\b\b\b\b\b\b\b\b\b\b\b\b");
i= 0;
/*
采用相同的方法掩盖明文密码
*/
do {
a.pwd[i]=getch();
if(a.pwd[i]=='\r')
break;
if(a.pwd[i]=='\b') {
if(i==0) {
printf("\a");
continue;
}
i=i-1;
printf("\b");
}
else {
i=i+1;
printf("*");
}
} while(a.pwd[i]!='\n' && i<20);
a.pwd[i]='\0';
printf("\n");
fp = fopen("Users.txt","r");
while (1) {
fread(&b, sizeof(Users), 1, fp); //读入一个结构体字符块 写入b
if ((strcmp(a.name, b.name)==0)||(!feof(fp))) { //如果有此账号
break; //此账号已经注册 可以登录
}
else {
if (!feof(fp)) { //如果文件没有读完
fread(&b, sizeof(Users), 1, fp);
}
else { //如果在变量用户表之后没有找到该账号,提示错误信息
printf("\t\t账号或密码错误!\n");
fclose(fp);
Sleep(1000);
system("cls");
return ;
}
}
}
fclose(fp);
if (strcmp(a.pwd, b.pwd)==0) { /*如果密码匹配*/
printf("\t\t登录成功!欢迎使用!\n");
return;
}
else {
printf("\t\t账号或密码错误!……");
Sleep(1000);
system("cls");
return;
}
}
/*
找回密码模块
*/
void Reback() {
system("cls");
Users a,b; //两个用于零时写入的结构体变量
FILE *fp;
printf("\t\t欢迎来到找回密码界面!\n\n");
int num = 0; //用于记录改密用户在文件中的位置
fp = fopen("Users.txt","r");
fread(&b, sizeof(Users), 1, fp); //读入一个用户信息并写入b
printf("\t\t请输入账号:[ \t\t ]\b\b\b\b\b\b\b\b\b\b\b\b\b");
scanf("%s",&a.name);
while (1) {
if (strcmp(a.name, b.name)==0) { //如果有此用户名
break; //就跳出完成查找
}
else {
if (!feof(fp)) { //如果文件没有读完切没有找到该用户
fread(&b, sizeof(Users), 1, fp); //继续查找用户
num++;
}
else { //如果没有找到
printf("\t\t此用户不存在!!!\n");
fclose(fp);
for(i=0; i<2; i++) {
printf("\t\t%d秒后退出 ……",2-i);
printf("\r");
Sleep(1000);
}
system("cls");
return;
}
}
}
//如果程序走到这 就可以开始修改密码了
int ver_code = 0,user_ver_code = 0;
//生成随机的验证码
srand((unsigned)time(NULL));
for (i = 0; i < 7; i++){
ver_code += rand() % 1000;
}
char phone_tail[5] ; // 获取该用户的手机尾号
strncpy(phone_tail,a.phone+7,4) ;
printf("\t\t已向尾号为%s的手机号码发送验证码 %d ,请注意查收!\n\t\t请输入验证码:[\t\t]\b\b\b\b\b\b\b\b\b\b", phone_tail,ver_code);
scanf("%d", &user_ver_code);
int sign = 0;
//给用户提供三次验证输入的机会
for(i=0; i<3; i++) {
if (ver_code != user_ver_code) {
printf("\t\t验证码错误!请重新输入:[\t](剩%d次机会)\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b",2-i);
scanf("%d", &user_ver_code);
continue;
}
else if (i<=3) { //如果验证次数内正确输入验证码
sign =1; //就可以退出循环
break; //向下一步改密
}
else {
for(i=0; i<2; i++) {
printf("\t\t多次输入错误!!%d秒后退出 ……",2-i);
printf("\r");
Sleep(1000);
}
}
}
if(sign == 1) { //如果验证手机正确开始改密
FILE*fp;
int N = 0; //用于记录当前用户总数
if((fp=fopen("Users.txt","r"))==NULL) { // 判断文件是否能打开
printf ("\t\tCannot open file\n");
exit(0);
}
else {
while (feof(fp)==0) {
fread(&b, sizeof(Users), 1, fp); //依次读取用户并记录用户总数
N++;
}
}
N = N-1; //实际用是完成上面循环的 N-1
fclose(fp);
Users user[N]; //定义结构体数组
if((fp=fopen("Users.txt","r"))==NULL) { // 判断文件是否能打开
printf ("\t\tCannot open file\n");
exit(-1);
}
else {
i=0;
do {
fread(&user[i],sizeof(Users),1,fp); //将用户表中的数据都读入以便修改指定用户的密码
} while(feof(fp)==0); //直到读到文件尾结束
}
printf("\t\t设置您的新密码:[ \t\t]\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
i= 0;
/*
让输入的密码不可见
*/
do {
user[num].pwd[i]=getch();
if(user[num].pwd[i]=='\r')
break;
if(user[num].pwd[i]=='\b') {
if(i==0) {
printf("\a");
continue;
}
i=i-1;
printf("\b");
}
else {
i=i+1;
printf("*");
}
} while(user[num].pwd[i]!='\n' && i<20);
user[num].pwd[i]= '\0';
printf("\n");
if ((fp=fopen("Users.txt","w"))==NULL) { /*判断文件是否能打开*/
printf ("\t\tCannot open file\n");
exit(0);
}
for (i=0; i<N; i++) /*将内存中的用户信息输出到磁盘文件中去*/
if (fwrite(&user[i],sizeof(Users),1,fp)!=1)
printf("File write error\n");
fclose(fp);
printf("\t\t密码修改成功!\n");
return ;
}
else {
for(i=0; i<3; i++) {
printf("\t\t多次输入错误!!%d秒后退出 ……",3-i);
printf("\r");
Sleep(1000);
}
}
}
五、重构软件测试
因我的改动是在原系统之外重新建一个.c源文件编程,几乎没有变更原系统的代码,所以我便不再重复贴上原系统截图,只附上新增系统的测试截图
(图片同样保存在百度网盘中)
六、总结
本次逆向软件工程对我来说难度相当大,首先是在一个已完成的系统找出可优化点,即使它出自与我同级的朋友手中也是让我绞尽脑汁,我也有过两次废稿:分别是新增数据库与优化用户界面,最终因能力有限而不得不放弃,选择扩增现有功能,及时退而求其次依旧花掉了我三天的时间查阅资料编写代码,也可以算的上收获颇丰。
浙公网安备 33010602011771号