BUAA(2021春)小型图书管理系统
BUAA数据结构第二次编程题——小型图书管理系统看前须知题目内容问题描述输入形式输出形式样例样例说明题解易错点和难点参考代码补充测试的数据推荐题单看前须知要点介绍和简要声明.题目内容问题描述小明同学特别喜欢买书看书。由于书较多,摆放杂乱,找起来非常麻烦。这学期小明同学上了数据结构与程序设计课后,决定改变这种状况:用C开发一个小型图书管理系统。系统中包含的图书信息有:书名、作者、出版社、出版日期等。
看前须知
第二次上机题汇总
题目内容
问题描述
小明同学特别喜欢买书看书。由于书较多,摆放杂乱,找起来非常麻烦。这学期小明同学上了数据结构与程序设计课后,决定改变这种状况:用C开发一个小型图书管理系统。系统中包含的图书信息有:书名、作者、出版社、出版日期等。首先,图书管理系统对已有的书(原始书库,存放在一个文本文件中)按**书名字典序进行(按书名中各字符的ASCII码值由小到大排序)**摆放(即将原始无序的图书信息文件生成一个有序的文件,即新书库),以便查找。该管理系统可以对新书库中图书条目进行如下操作:
- 录入。新增书录入到书库中(即从输入中读入一条图书信息插入到已排序好的图按书文件相关位置处)
- 查找。按书名或书名中关键字信息在书库中查找相关图书信息,若有多本书,按字典序输出。
- 删除。输入书名或书名中关键字信息,从书库中查找到相关书并将其删除,并更新书库。
输入形式
原始的图书信息(原始书库)保存在当前目录下的books.txt中。
用户操作从控制台读入,首先输入操作功能序号(1代表录入操作,2代表查找操作,3代表删除操作,0代表将已更新的图书信息保存到书库中并退出程序),然后在下一行输入相应的操作信息(录入操作后要输入一条图书信息,查找和删除操作后只要输入书名或书名中部分信息)。程序执行过程中可以进行多次操作,直到退出(输入操作0)程序。
要求:
- 原始文件中的图书信息与录入的图书信息格式相同,每条图书信息都在一行上,包括****书名(不超过50个字符)、作者(不超过20个字符)、出版社(不超过30个字符)和出版日期(不超过10个字符),只由英文字母和下划线组成,用一个空格分隔。图书信息总条数不会超过500.
- 下划线字符参加排序。
- 图书不会重名。
输出形式
进行录入和删除操作,系统会更新图书信息,但不会在控制台窗口显示任何信息。
进行查找操作后,将在控制台按书名字典序分行输出查找到的图书信息,书名占50个字符宽度,作者占20个字符宽度,出版社占30个字符宽度,出版日期占10个字符宽度,都靠左对齐输出。
最终按字典排序的图书信息保存在当前目录下的ordered.txt中,每条图书信息占一行,格式与查找输出的图书信息相同。
样例
【样例输入】
假设books.txt中保存的原始图书信息为:
The_C_programming_language Kernighan Prentice_Hall 1988
Programming_in_C Yin_Bao_Lin China_Machine_Press 2013
Data_structures_and_Algorithm_Analysis_in_C Mark_Allen_Weiss Addison_Wesley 1997
ANSI_and_ISO_Standard_c Plauger Microsoft_Press 1992
Data_structures_and_program_design_in_C Robert_Kruse Pearson_Education 1997
Computer_network_architectures Anton_Meijer Computer_Science_Press 1983
C_programming_guidelines Thomas_Plum Prentice_Hall 1984
Data_structures_using_C Tenenbaum Prentice_Hall 1990
Operating_system_concepts Peterson Addison_Wesley 1983
Computer_networks_and_internets Douglas_E_Come Electronic_Industry 2017
用户控制台输入信息为:
1
Data_structures_and_C_programs Christopher Addison_Wesley 1988
2
structure
1
The_C_programming_tutor Leon_A_Wortman R_J_Brady 1984
2
rogram
3
rogramming
0
【样例输出】
用户输入“2 structure”后,控制台输出:

用户输入“2 rogram”后,控制台输出:

ordered.txt文件内容为:
样例说明
先读入books.txt中的10条图书信息,按照书名进行字典序排序;用户进行了五次操作,然后退出:第一次操作是插入了一条图书信息,这时有11条图书信息,按书名字典序排序为:
ANSI_and_ISO_Standard_c Plauger Microsoft_Press 1992
C_programming_guidelines Thomas_Plum Prentice_Hall 1984
Computer_network_architectures Anton_Meijer Computer_Science_Press 1983
Computer_networks_and_internets Douglas_E_Come Electronic_Industry 2017
Data_structures_and_Algorithm_Analysis_in_C Mark_Allen_Weiss Addison_Wesley 1997
Data_structures_and_C_programs Christopher Addison_Wesley 1988
Data_structures_and_program_design_in_C Robert_Kruse Pearson_Education 1997
Data_structures_using_C Tenenbaum Prentice_Hall 1990
Operating_system_concepts Peterson Addison_Wesley 1983
Programming_in_C Yin_Bao_Lin China_Machine_Press 2013
The_C_programming_language Kernighan Prentice_Hall 1988
第二次操作是查找书名包含structure的图书,有4本图书信息按照格式要求输出到屏幕;第三次操作又插入了一条图书信息,这时有12条图书信息;第四次操作查找书名包含rogram的图书,有6本图书信息按照格式要求输出到屏幕;第五次操作是删除书名包含rogramming的图书信息,有四条图书信息要删除,剩下八条图书信息;最后退出程序前将剩余的八条图书信息按照格式要求存储在ordered.txt文件中。
题解
易错点和难点
这题其实就是在模拟图书馆,本题的难点有二。
第一是结构体的排序,对于结构体的多级排序的操作,用qsort是最容易解决的,要注意sizeof里面应该是结构体的大小,关键就在于怎么编写qsort中的cmp(const voidp1,const voidp2)函数,这里其实就是套路,首先先进行结构体指针的转换,之后在按照要求进行return 中的内容比较,如果是多级排序,则是是用条件判断语句 if 进行多级return操作就可以了。
第二是仔细审题,有相当一部分同学是输出错误,要注意读入信息是书本信息那四者之间有空格,而输出信息是实际上是没有空格的。
参考代码
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
#define M 600
struct book { //图书馆结构体
char title[M]; //书名
char author[M];//作者
char pub[M]; //出版社
char year[M]; //出版日期
};
typedef struct book Book;
typedef struct book *Bookp;
int cmp(const void*p1,const void*p2);
int main() {
int i=0,j=0,type=0; //type是操作类型
int cnt=0;
char tmp[M];
Book infor[M]; //书本信息存储
FILE *fp1 = fopen("books.txt","r");
FILE *fp2 = fopen("ordered.txt","w");
if(fp1==NULL||fp2==NULL) {
printf("Can nou find this file");
} else {
while(~fscanf(fp1,"%s %s %s %s",&infor[cnt].title,&infor[cnt].author,&infor[cnt].pub,&infor[cnt].year)) {
cnt++; //记录书本本数
}
qsort(infor,cnt,sizeof(Book),cmp); //先排序
while(~scanf("%d",&type)) {
if(type==1) { //加入书籍
scanf("%s %s %s %s",&infor[cnt].title,&infor[cnt].author,&infor[cnt].pub,&infor[cnt].year);
cnt++; //记录书本本数
qsort(infor,cnt,sizeof(Book),cmp); //排序
} else if(type==2) { //查找操作
scanf("%s",tmp); //输入关键信息
for(i=0; i<cnt; i++) {
if(strstr(infor[i].title,tmp)!=NULL) { //找到关键信息
printf("%-50s%-20s%-30s%-10s\n",infor[i].title,infor[i].author,infor[i].pub,infor[i].year);
}
}
} else if(type==3) { //删除操作
scanf("%s",tmp); //输入关键信息
for(i=0; i<cnt; i++) {
if(strstr(infor[i].title,tmp)!=NULL) { //找到关键信息
memset(infor[i].title,0,sizeof(infor[i].title)); //清空
}
}
qsort(infor,cnt,sizeof(Book),cmp);
} else if(type==0) {
break;
}
}
for(i=0; i<cnt; i++) {
if(infor[i].title[0]=='\0') continue;//如果是清空的信息,则不输出
else {
fprintf(fp2,"%-50s%-20s%-30s%-10s\n",infor[i].title,infor[i].author,infor[i].pub,infor[i].year);
}
}
}
fclose(fp1);
fclose(fp2);
return 0;
}
int cmp(const void*p1,const void*p2) { //按照书名按字典序排序
struct book *a=(struct book*)p1;
struct book *b=(struct book*)p2;
return strcmp(a->title,b->title);
}
补充测试的数据
没有特别的测试数据,全部都是中规中矩的
推荐题单
更多推荐


所有评论(0)