图书管理系统
1.设计思路图
- 考虑好要实现的功能及先后顺序 搭建好框架 再用函数分开实现各个模块的功能。
2. 应考虑到的问题
1)用户名 书名输入问题 要限定长度 范围。
2)密码问题一般范围在字母数字。还有考虑输入错误的次数 一般为三次自动退出。还有文件中存储的密码最好要加密。(可以用isdigit(ch)isalpha(ch))来判断)
3)书本数定义为整形时应考虑输入为如果为浮点型时会造成的错误。
4)借书时应考虑库存位0时无法借书。学生在借书还书时应分别打印出图书清单和个人已借清单,方便查阅。
5)学生注册学号不能重复应限定为一定长度(eg:限定为8位的数字)可以用字符的ASCⅡ值作为判断看是否满足条件。
6)借书还书库存改 斜体文本变可以在学生的信息中加入二维字符数组记录所借书的编号,当学生借阅情况改变时便利图书信息的链表更改库存和借出数。
3.部分代码
1. eg:管理员密码的输入(密码限定在一定范围内)
- 使用goto语句 if判断条件 如果密码的长度不对会跳到指定的步骤再次输入
void manager_password(char password[]) //管理员密码输入
{
char ch;
int p=0;
loon: while ((ch=getch()),ch!='\r') //判断是否为回车
{
if(ch==8) //看字符是否为返回键
{
if(p>0)
{
printf("\b \b");
p--;
}
continue;
}
if(!isdigit(ch)&&!isalpha(ch))
//isdigit检查其参数是否为十进制数字字符。
//isalpha字符是一个英文字母 是返回非零值 不是返回0
{
continue;
}
putchar('*');
password[p++]=ch; //保存密码
}
if(p<6||p>10)
{
printf("\n\t\t\t请按正确格式输入6~10位密码!");
printf("\n\n\t\t\t请重新输入:");
p=0;
goto loon;
}
password[p]=0; //字符串结束符
}
2.当你的switch case 语句中的判断条件为一个整型或字符型数时,你可以在输入下面加上 这段简短的代码以防暴力输入(输入一大堆字符串等)。
while(getchar()!='\n')
continue;
3.把链表中的东西存入文件中可能会出现文件乱码的情况:
我遇到过这种现象 将链表中的信息加入文件中 链表的最后不能加多余的字符 因为读到最后有多余的字符造成一大堆乱码
(解决方法如下)
void Save_manager(manager *h2) //存储管理员信息在文件中
{
FILE *fp;
manager *t=h2->next;
if((fp=fopen("manager.txt","wt"))==NULL){
printf("\t\t打开失败\n");
getch();
exit(1);
}
while(t->next)
{
fprintf(fp,"%s ",t->name);
fprintf(fp,"%s ",t->number);
fprintf(fp,"%s\n",t->password);
t=t->next;
}
fprintf(fp,"%s ",t->name);
fprintf(fp,"%s ",t->number);
fprintf(fp,"%s",t->password); //链表的最后不能加多余的字符以防从文件读取信息时
t=t->next; //读到最后有多余的字符造成一大堆乱码
fclose(fp);
}
4.总结
- 通过这次写管理系统我认识到最开始时类型定义及框架的设计是很重要的。就拿我之前写通讯录的经验来说吧 刚开始用结构体写 第二次用链表来实现相同的功能代码就要整体改一遍。可见开始的设计思路及其重要。
- 还有就是函数的分装也很重要 就比如密码的输入可以写在一个函数里 管理员和学生密码输入都可以调用这个函数,使代码看起来更简洁。
- 再者 就是要考虑很多现实因素 比如学号的限定 库存为0时提示不能借书 密码输入的长度 次数 加密等问题。