C语言图书管理系统

图书管理系统

一、系统功能

图书管理系统要求实现图书管理的基本功能,包括图书的录入、删除、查找和导入/导出等。图书的属性包括书号、书名、第一作者、版次、出版社、出版年等信息。

功能要求:

1.创建:创建图书管理系统,用逐条输入的方式;

2.显示:分屏显示图书管理系统中的所有记录;

3.插入:向图书管理系统中插入一条记录;

4.删除:删除一条已经存在的记录项;

5.排序:以编号为依据升序排列所有记录项;

6.查找:根据用户输入的属性值查找符合条件的记录项;

7.导入/导出:可以从文件读入已有的图书管理系统,也可将系统中的图书信息导出到文件;

8.反序:以编号为依据将按序排列的记录项反序排列;

9.删除相同记录。

构建如图菜单系统,程序执行过程为:循环显示主菜单,用户在Give your choice:处输入选项,即按照功能列表输入0~10中的任意一个数字,按回车后,执行相应的功能。功能执行完毕,返回菜单。

二、菜单功能

各菜单项功能如下:

(1)Input Records(建立有序表)

从键盘上一次输入一条图书记录(书号、书名、第一作者、版次、出版社、出版年),以“书号”为序建立有序表。插入一条记录后,显示提示信息:确认是否输入下一条记录,如确认,继续输入,否则,退出输入功能。

(2)Display All Records(显示所有结点记录)

按顺序显示表中所有记录,每屏显示10条记录,按<Enter>键继续显示下一屏。

(3)Insert a Record(插入一条结点记录)

在以“书号”为序排列的表中插入一条记录,插入后,表仍有序。输出插入成功的信息。

(4)Delete a Record(按“书号”查找,找到后删除该条结点记录)

输入待删除记录的“书号”,显示提示信息,让用户再次确认是否要删除。确认后,将该“书号”的记录删除。

(5) Sort(排序)

以“书号”为升序排列表中的记录。

(6)Query(查找并显示一个结点记录)

输入“书号”,查找该记录,找到后显示记录信息。

(7)Add Records from a Text File(从文件中添加数据到系统中)

用户可事前建立一个文件data.txt,存放多条待加入的记录。提示输入文件的文件名,然后从该文件中一次性加入多条图书记录。文件data.txt格式如下(可以使用英文或拼音表示中文信息):

注意:该文件中第一行的数字表示待添加的记录数,下面每行为图书记录。

(8)Write to a Text File(将系统中记录写入文件)

将图书管理系统中的全部记录写入文件records.txt,要求文件格式和文件data.txt相同。

(9)Reverse List(将表反序)

将表中的所有结点按“书号”反序存放。

(10)Delete the Same Records(删除相同记录)

删除书名、第一作者、版次、出版社、出版年均相同的记录。

(0)Quit(退出图书管理系统程序)

退出图书管理系统程序。

三、实现要求

1. 数据结构

用结构体数组实现图书信息的记录和管理。每个数组元素为一个结构体变量

在主函数中定义结构体数组Bookinfo books[NUM];用作记录存储,也可采用动态链表实现。

2. 各函数功能

以下函数原型说明中出现的函数为本课程设计的基本要求。请不要更改函数原型。

(1)数据输入

int Input(Bookinfo dictList[],int n);

从键盘输入若干条记录,依次存放到结构体数组dictList中,n为数组原有记录数,函数返回最后的记录数。

(2)输出数据

void Diplay(Bookinfo dictList[],int n);

显示所有图书信息,每10本暂停一次,n为数组元素个数。

(3)插入一条结点记录

int Insert(Bookinfo dictList[],int n, Bookinfo *s);

按书号序插入记录s,返回记录个数。

int Insert_a_record(Bookinfo dictList[],int n);

输入待插入的图书书号、书名、作者、版本号、出版社名、出版年等图书信息,调用Insert函数按书号作有序插入,输出插入成功信息,返回记录个数。

(4)删除一条结点记录

int Delete(Bookinfo dictList[],int n, char *book);

删除书名为book的第一条图书记录,返回数组中的记录数。

int Delete_a_record(Bookinfo dictList[],int n);

输入待删除的书名,经确认后调用Delete函数,同时列出同一书名的所有书目,输入待删除书目的书号,提示是否删除,确认后,输出删除成功与否的信息,返回数组中的记录数。

(5)排序

void Sort_by_ISBN(Bookinfo dictList[],int n);

数组按书号升序排列。

(6)查询数据

int Query(Bookinfo dictList[],int n, char *book);

查找并显示书名为book的所有记录,查找成功返回该书名记录个数,否则返回-1。

void Query_a_record(Bookinfo dictList[], int n);

输入待查找的书名,调用Query函数查找该书的记录,输出查找成功与否的信息和该书名的所有记录。

(7)从文件中整批输入数据

int AddfromText(Bookinfo dictList[],int n, char *filename);

从文件filename添加一批记录到数组中,调用Insert()函数作有序插入,返回添加记录后的新记录数。

(8)将记录写到文件

void WriteText(Bookinfo dictList[],int n,char *filename);

将数组中的记录全部写入文件filename中。

(9)将表反序存放

void  Reverse(Bookinfo dictList[]);

按书号反序存放表。

(10)删除雷同记录

int DeleteSame(Bookinfo dictList[], int n);

删除数组中书名、作者、版本号、出版社名、出版年均相同的记录,n为数组原有记录数,函数返回最后的记录数。

(0)退出管理系统

void Quit(Bookinfo dictList[]);

退出系统时,释放动态存储空间。

其他函数

void Display_Main_Menu();

显示主菜单。

实验过程中可以根据需要适当增加函数,以使程序算法更清晰明了。

其中部分函数是我补充添加的(具体看代码标注)。

#include<stdio.h>
#include<windows.h>
#include<math.h>
typedef struct          //定义数据类型
{
	char ISBN[10];      //书号
	char book[30];      //书名
	char author[20];    //作者
	int edition;        //版本号
	char press[50];     //出版社名
	int year;           //年份
}Bookinfo;

int Input(Bookinfo dictList[],int n)       // 从键盘输入若干条记录,依次存放到结构体数组dictList中,返回最后的记录数
{
	int m,i;                               //m:要输入的本数,i循环控制量

	printf("请输入要输入图书的本数n");
	scanf("%d",&m);
	getchar();
	printf("n");
	for(i=0;i<m;i++)
	{
		printf("请输入第%d本:n",i+1);
		printf("书号:");
		gets(dictList[n+i].ISBN);
		printf("书名:");
		gets(dictList[n+i].book);
		printf("作者:");
		gets(dictList[n+i].author);
		printf("版本号:");
		scanf("%d",&dictList[n+i].edition);
		getchar();
		printf("出版社名:");
		gets(dictList[n+i].press);
		printf("出版年份:");
		scanf("%d",&dictList[n+i].year);
		getchar();
		printf("n");
	}
	printf("输入完毕!请继续:");
	return (n+m);           //返回总的图书本数
}

void Display(Bookinfo dictList[],int n)        //显示所有图书信息,每10本暂停一次
{
	int i,js=1;                                //js:计数,统计已经输出的本数
	char zt;
	printf("n");
	printf("书号          书名    作者            版本号     出版社      出版年份n");
	printf("---------------------------------------------------------------------n");
	printf("n");
	for(i=0;i<n;i++,js++)
	{
		printf("%-8s",dictList[i].ISBN);                                                          //利用格式控制,表示向左对齐8个,默认也是向左对齐
		printf("%-15s",dictList[i].book);                                                         
		printf("%-13s",dictList[i].author);
		printf("第%3d版 ",dictList[i].edition);
		printf("%-14s",dictList[i].press);
		printf("%dn",dictList[i].year);
		if((++js)%20==0)                       //每输出十本换行
		{

			printf("n              任意键,继续输出n");            //输出了10个之后,暂停+提示
			system("pause");
			zt=getchar();
		}
	}
	printf("输出完毕!请继续:");
}

int Delete(Bookinfo dictList[],int n,char *book) //删除某一本书
{
	int i,j,t;
	char del[10],c,*zj;  //del删除的目标书号

	printf("请选择书号:   ");
	gets(del); 
	getchar();
	for(i=0;i<n;i++)                                //通过遍历寻找是否有对应书号的书籍,找到便将其删除
	{
		for(j=0,zj=book;j<30 && dictList[i].book[j]!='';j++,zj++)    
		{
			if(dictList[i].book[j]==*zj) t=1;    //找到的时候,令t=1                 
			else {t=0;j=30;}
		}
		if(t==1)                                  //进入删除功能,将其删除
		{
			for(j=0;j<10 && dictList[i].ISBN[j]!='';j++)
			{
				if(dictList[i].ISBN[j]==del[j]) t=1;
				else {t=0;j=10;}
			}
			printf("确定删除,请按回车键!");
			c=getchar();                              //万能getchar,加一个
			if(c!='n') t=0;
			if(t==1)
			{
				for(;i<n-1;i++)
				{
					dictList[i]=dictList[i+1];               //删除了后将删除后面的往左边挪动一位
				}
			}
		}
	}
	printf("成功删除");
	return n-1;
}

int Delete_a_record(Bookinfo dictList[],int n)
{
	int i,t,p;
	char sm[30],*book,ch; //sm:书名,待删除书名

	printf("请输入待删除书本的名字:");
	getchar();
	gets(sm);
	book=&sm[0];
	printf("是否删除?若要删除请按y;否则请按其他键 n");
	scanf("%c",&ch);
	getchar();
	if(ch=='y')
	{
	for(i=0;i<n;i++)                                         //这部分是展示要删除的书籍
	{
		for(p=0;p<30 && dictList[i].book[p]!='';p++)       //找一遍,找到了就让t为1,展示其信息,并调用删除函数
		{
			if(dictList[i].book[p]==sm[p]) t=1;
			else {t=0;p=30;}
		}
		if(t==1)
		{
			printf("书号    书名n");
	        printf("____________n");
			printf("%-8s",dictList[i].ISBN);
		    printf("%-8sn",dictList[i].book);
		}
	}
	
	n=Delete(dictList,n,book); 
	}
	else
		printf("删除失败!  n");                           
	return n;                           //返回删除书籍的记录数
}

void Sort_by_ISBN(Bookinfo dictList[],int n)      //数组按书号升序排列
{
		int i,j,p,bj;
		Bookinfo ls;

	for(i=0;i<n-1;i++)
	{
		p=i;
		for(j=i+1;j<n;j++)
		{
			bj=strcmp(dictList[i].ISBN,dictList[j].ISBN);                     //通过这个判断书号是否相等
			if(bj>0) p=j;                                                     //当左边的大,则保持原来排序
		}
		if(p!=i)                                                              //当右边的大,则进行替换
		{
			ls=dictList[i];
			dictList[i]=dictList[p];
			dictList[p]=ls; 
		}
	}
	printf("排序完成n");
}

void Sort_by_name(Bookinfo dictList[],int n)      //数组按书名升序排列,同书号排序的逻辑
{
		int i,j,p,bj;
		Bookinfo ls;

	for(i=0;i<n-1;i++)                    //同样采用选择比较进行排序
	{
		p=i;
		for(j=i+1;j<n;j++)
		{
			bj=strcmp(dictList[i].book,dictList[j].book);
			if(bj>0) p=j;
		}
		if(p!=i)
		{
			ls=dictList[i];
			dictList[i]=dictList[p];
			dictList[p]=ls;
		}
	}
	printf("排序完成n");
}

int Insert(Bookinfo dictList[],int n,Bookinfo *s) //有序插入
{
	int i,j,p;

	for(i=0;i<=n;i++)
	{
		p=strcmp(dictList[i].book,(*s).book);                    //将插入数据的放到第i个
		if(i=n)                                                  //如果插入的在最后,则直接插入
		{
			dictList[i]=*s;
			i=n+1;
			j=n+1;
		}
		if(p>0)                               
		{
			for(j=n;j>i;j--) dictList[j]=dictList[j-1];          //如果插入的在中间,则将插入点之后的数据向右挪动一个位置
			dictList[i]=*s;
			i=n+1;
		}
        
	}
	return(n+1);
}

int Insert_a_record(Bookinfo dictList[ ],int n)  //有序插入
{
	Bookinfo mmp,*s;
	s=&mmp;
	getchar();
	printf("书号:");
	gets(mmp.ISBN);
	printf("书名:");
	gets(mmp.book);
	printf("作者:");
	gets(mmp.author);
	printf("版本号:");
	scanf("%d",&mmp.edition);
	getchar();
	printf("出版社名:");
	gets(mmp.press);
	printf("出版年份:");
	scanf("%d",&mmp.year);
	getchar();
	n=Insert(dictList,n,s);
	Sort_by_ISBN(dictList,n);
	printf("插入成功"); 
	return n;
}



int Query(Bookinfo dictList[],int n,Bookinfo *book)       //查找并显示书名为book的所有记录,查找成功返回该书记录个数,失败则返回0
{
	int i,p,t,m=0;

	for(i=0;i<n;i++)                                      //利用for循环寻找是否有书名与之对应的
	{
		for(p=0;p<30 && dictList[i].book[p]!='';p++)
		{
			if(dictList[i].book[p]==(*book).book[p]) t=1;
			else {t=0;p=30;}
		}
		
		if(t==1)                                         //如果找到了,就将其定为1,并输出相关信息
		{
			printf("书号    书名    作者     版本号     出版社 出版年n");
	        printf("__________________________________________________n");
			printf("%-8s",dictList[i].ISBN);
		    printf("%-8s",dictList[i].book);
		    printf("%-8s",dictList[i].author);
		    printf("第%3d版     ",dictList[i].edition);
		    printf("%-8s",dictList[i].press);
		    printf("%dn",dictList[i].year);
			m=m+1;
		}
	}
	return m;
}

void Query_a_record(Bookinfo dictList[],int n)         //输入待查书名
{
	Bookinfo cz,*czz;
	int a,i;

	czz=&cz;
	printf("请输入要查找的书名:");
	getchar();
	gets(cz.book);
	a=Query(dictList,n,czz);
	if(a>0)
		printf("找到了%d本名为%s的书!",a,cz.book);
	else
		printf("没有找到名称为%s的书",cz.book);
}

void WritetoText(Bookinfo dictList[],int n,char *filename)         //将记录写到文件里
{
	int i;
	FILE *fp;

	fp=fopen(filename,"w");
	if(fp==NULL)
	{
		printf("不能打开文件n");
		exit(1);                                                  //没打开成功就exit
	}
	fprintf(fp,"%dn",n);
	//fprintf(fp,"书号          书名    作者     版本号     出版社      出版年份n");
	//fprintf(fp,"--------------------------------------------------------------n");
	for(i=0;i<n;i++)
	{
		fprintf(fp,"%s %s %s %d %s %d",dictList[i].ISBN,dictList[i].book,dictList[i].author,dictList[i].edition,dictList[i].press,dictList[i].year);
		printf("n");
	}
	printf("成功记录到文件!");
	fclose(fp);
}

int AddfromText(Bookinfo dictList[],int n,char *filename)   //从文件中导入数据
{
	int i;

    Bookinfo s;
	FILE *p;
    system("cls");
    p=fopen(filename,"r");
	if(p==NULL)
		printf("文档打开失败!n");
	else
		printf("文档打开!n");
    fscanf(p,"%d",&i);
    while(!feof(p))                           //与写入数据那一段相对应
    {
        fscanf(p,"%s %s %s %d %s %d",s.ISBN,s.book,s.author,&s.edition,s.press,&s.year);
        n=Insert(dictList,n,&s);                          
    }
    fclose(p);
    printf("成功输入n");
	fclose(p);
    return(n);                
}
void Reverse(Bookinfo dictList[],int n)                                //反序排序,这里只不过把之前的程序改一个符号
{
int i,j,p,bj;
		Bookinfo ls;

	for(i=0;i<n-1;i++)
	{
		p=i;
		for(j=i+1;j<n;j++)
		{
			bj=strcmp(dictList[i].ISBN,dictList[j].ISBN);
			if(bj<0) p=j;                                                 //大于小于号改了,这个是选择排序
		}
		if(p!=i)                                                         //变为小于号,如果右边的小,则与左边的进行替换,用ls作为中间量
		{
			ls=dictList[i];
			dictList[i]=dictList[p];
			dictList[p]=ls;
		}
	}
	printf("排序完成n");
}

void copyBook(Bookinfo *a,Bookinfo b)                                //这个是给删除同一书的函数服务的函数
{
strcpy(a->author,b.author);                                         //这个是将后面的赋给前面的a
strcpy(a->book,b.book);
a->edition = b.edition;
strcpy(a->ISBN,b.ISBN);
strcpy(a->press,b.press);
a->year = b.year;
}

int SameBook(Bookinfo a, Bookinfo b)                                        //这个是判断是否为重复书籍的函数,删除同书的函数循环调用此函数
{
	return !strcmp(a.author, b.author)                                      //如果找到了作者、书名、出版社、出版编号、日期相同的书,则该书为相同书
		&& !strcmp(a.book, b.book)
		&& (a.edition == b.edition)
		&& !strcmp(a.press, b.press)
		&& (a.year == b.year);
}

int DeleteSame(Bookinfo dictList[], int n)                                            //删除相同的书籍
{
	int i, j;
	int newLen = n;
	for (i = 0; i < newLen - 1; i++) 
	{

		for (j = i + 1; j < newLen; j++) 
		{
			if (SameBook(dictList[i], dictList[j]))
			{
				for (int k = j; k < n - 1; k++)
				{
					dictList[k] = dictList[k + 1];                      //向左挪动一个位置                            
				}
				--newLen,--j;
			}

		}
	}
	printf("已删除相同的书籍数据,返回记录数为: %d", newLen);
	return newLen;
}

int menu_select()                                   //我设计的菜单
{
	int sn;
	system("cls");                      //清屏
	 printf("                                           The Book Manangement Systemm                   n");
	printf("                     |--------------------------------------------------------------------|n");
	printf("                     |                              Menu                                  |n");
	printf("                     |--------------------------------------------------------------------|n");
	printf("                     |                     1 Input Records                                |n");
	printf("                     |                     2 Display All Records                          |n");
	printf("                     |                     3 Insert a Record                              |n");
	printf("                     |                     4 Delete a Record                              |n");
	printf("                     |                     5 Sort                                         |n");
	printf("                     |                     6 Query                                        |n");
	printf("                     |                     7 Add Records from a Text File                 |n");
	printf("                     |                     8 Write to a Text File                         |n");
	printf("                     |                     9 Correct a record                             |n");
	printf("                     |                     10 Search author                               |n");
	printf("                     |                     11 Reverse                                     |n");
	printf("                     |                     12 Delete The Same Records                     |n");
	printf("                     |                     13 Sort by name                                |n");
	printf("                     |                     0 Quit                                         |n");
	printf("                     |--------------------------------------------------------------------|n");
	printf("                                         Please enter your choice(0~13):   ");

	for(; ;)                                 //用死循环判断用户是否输入的是13的数字,如果输入14则提示错误重输
	{
		scanf("%d",&sn);
		if(sn<0||sn>13)
			printf("n输入错误,重选0~13:");
		else
			break;
	}
	return sn;
}

void Correct(Bookinfo dictList[],int n)   //显示所有记录,并对其中某一个进行修改
{
	char xg[30];
	int i,bj,m;
	
	Display(dictList,n);
	system("pause");
	printf("请输入所要修改图书记录的书号:n");
	scanf("%s",xg);
	for(i=0;i<n;i++)
	{
		bj=strcmp(dictList[i].ISBN,xg);
		if(bj==0)  break;
	}
	
	printf("所要修改对象信息如下:n");
	printf("书号          书名    作者     版本号     出版社      出版年份n");
	printf("--------------------------------------------------------------n");
	printf("%-7s",dictList[i].ISBN);
	printf("%-16s",dictList[i].book);
	printf("%-8s",dictList[i].author);
	printf("第%3d版     ",dictList[i].edition);
	printf("%-14s",dictList[i].press);
	printf("%dn",dictList[i].year);
	printf("请输入所要修改对内容的序号n");
	printf("1.书号n2.书名n3.作者4.版本号n5.出版社n6.出版年份n");
	scanf("%d",&m);
	switch (m)                                                        //建立交互系统,确认要选择的修改部分
	{
	case 1:    
		{
			printf("书号:");
			scanf("%s",dictList[i].ISBN);
			break;
		}
	case 2:    
		{
			printf("书名:");
			scanf("%s",dictList[i].book);
			break;
		}
	case 3:    
		{
			printf("作者:");
			scanf("%s",dictList[i].author);
			break;
		}
	case 4:    
		{
			printf("版本号:");
		    scanf("%d",&dictList[i].edition);
		    getchar();
			break;
		}
	case 5:    
		{
			printf("出版社:");
			scanf("%s",dictList[i].press);
			break;
		}
	case 6:    
		{
			printf("出版年份:");
		    scanf("%d",&dictList[i].year);
		    getchar();
			for(; ;)                                 //用死循环判断用户是否输入的是1到6的数字,如果输入7则提示错误重输
	{
		scanf("%d",&m);
		if(m<1||m>6)
			printf("n输入错误,重选1~6:");
		else
			break;
		}
	}
	
}
}

void search_author(Bookinfo dictList[],int n)                         //查询作者在该管理系统有多少本书
{
	int i,t,p,count=0;
	char sm[30],*author; 
	printf("Input author_namen");
	getchar();
	gets(sm);
	author=&sm[0];
	for(i=0;i<n;i++)
	{
		for(p=0;p<30 && dictList[i].author[p]!='';p++)
		{
			if(dictList[i].author[p]==sm[p]) t=1;
			else {t=0;p=30;}
		}
		if(t==1)
		{
			count++;
		}
	}
	printf("The number of books by the author: ");
	printf("%d",count);

}

int play()                                             //*符号为打印出的心形图案符号
{
  float a,x,y;
    for(y=1.5f; y>-1.5f; y-=0.1f)
    {
        for(x=-1.5f; x<1.5f; x+=0.05f)
        {
            a = x*x+y*y-1;
            char c = a*a*a-x*x*y*y*y<=0.0f?'*':' '; 
            putchar(c);  
        }
        printf("n");
   }
   return 0;
}
int main()
{
	system("color B5");                                 //将菜单变为浅紫色
	int n=0;
	char i;
	Bookinfo dictList[50];
	Bookinfo favorites[50];
	for(;;)
	{
		switch(menu_select())                    //老师给的交互系统
		{
		case 1:
			{
				n=Input(dictList,n);
				system("pause");
				break;
			}
		case 2:
			{
				Display(dictList,n);
				system("pause");
				break;
			}
		case 3:
			{
				n=Insert_a_record(dictList,n);
				system("pause");
				break;
			}
		case 4:
			{
				n=Delete_a_record(dictList,n);
				system("pause");
				break;
			}
		case 5:
			{
				
				Sort_by_ISBN(dictList,n);
				system("pause");
				break;
			}
		case 6:
			{
				Query_a_record(dictList,n);
				system("pause");
				break;
			}
		case 7:
			{
				char *filename,s[30];
				printf("请输入文件名n");
				scanf("%s",s);
				filename=s;
				n=AddfromText(dictList,n,filename);
				system("pause");
				break;
			}
		case 8:
			{
				char *filename,s[30];
				printf("请输入文件名n");
				scanf("%s",s);
				filename=s;
				WritetoText(dictList,n,filename);
				system("pause");
				break;
			}
		case 9:
			{
				Correct(dictList,n);
				system("pause");
				break;
			}
		case 10:
			{
				search_author(dictList,n);
				system("pause");
				break;
			}
		case 11:
			{
				Reverse(dictList,n);
				system("pause");
				break;
			}
		case 12:
			{
				n = DeleteSame(dictList,n);
				system("pause");
				break;
			}
		case 13:
			{
				Sort_by_name(dictList,n);
				system("pause");
				break;
			}
		case 0:
			{
				play();
				printf("                         Goodbye!");
				printf("nnn");
				system("pause");
				exit(0);
			}
		}
	}
}

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>