C语言课程设计——图书期刊信息管理系统

C语言的一个课程设计

题目

图书期刊信息管理系统
阅览室对所收藏的图书与期刊信息实现计算机管理,为用户提供图书信息的查询。阅览室陈列若干工具书、期刊和其他书籍供读者在阅览室内查阅。同一刊物可以有去年和当年的多期同时放在书架上。阅览室的图书信息使用文件保存,按照书名排序。有新书刊到达时,工作人员将新书的信息添加到文件中。书籍的信息包括书刊编号、书名、出版单位、出版时间、价格、书籍分类号等,其中,期刊的书名包括刊物名称与年份期数,例如:读者-2014-21。每年的7月份开始,上一年的期刊将陆续从书架上撤走,装订成册,变成合订本上架,同时,图书信息文件中要刑去这些已经撤走的过期期刊的信息,添加合订本期刊的信息,例如,书名为读者-2014合。
图书期刊信息管理系统提供对书籍信息的录入与删除功能,提供图书信息的浏览与查询功能。其中,查询可以是对书名、出版单位、书籍分类号的模糊查询。例如,按书名查询时,输人“计算”,可以查到书名中含有“计算”字样的书刊,如计算方法(书籍)、微型计算机(期刊)、计算机工程(期刊)、英汉计算技术词典(工具书)等,这些都是符合条件的查询结果。再如,按照出版单位查询时,输入“大学”进行查询,则将阅览室收藏的所有大学出版社出版的书刊名称列出。按书籍分类号查询时,只要分类号前几位与所提供的相符即是符合条件。

需求分析

书籍的信息包括书刊编号、书名、出版单位、出版时间、价格、书籍分类号,需要定义一个book的结构体,包含以上信息,还要定义一个next指针,实现链表操作。
书籍信息按书名首写字母排序存放进文件中,书籍信息以空格或制表符分开,每一行存放不同的书籍信息。
程序所需要完成的功能是对书籍信息的录入与删除功能,提供图书信息的浏览与查询功能。
程序首先从文件中读取数据放进链表中,接下来的增加删除录入查询操作基于链表实现。
其中,增加结点时,是在链表尾部加一个结点,然后对链表进行排序,保证链表中的结点是按照书名从小到大排序。删除功能就是输入信息,找到这个结点并删除。浏览功能将文件中存储的全部书籍信息输出,查询功能输入信息,遍历链表,通过字符串匹配查找结点,若成功找到就输出结点信息。其中查询功能又分为按书名查找,按出版单位查找,按书籍分类号查找。程序结束时将链表写入文件中,更新文件信息。

概要设计

系统的模块划分
根据需求分析对系统进行下图所示的功能模块划分。图一

数据文件
本系统作为书籍信息来源的信息文件是file.txt,在程序中通过#define filename “file.txt”预定义。
在文本文件中,每本书籍的数据各占一行,每两项数据之间以空格或制表符分开,不含有表头文字。文件内容如下形式:在这里插入图片描述分别对应书籍编号,书名,出版单位,出版时间年,出版时间月,价格和书籍分类号。

具体代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define filename "file.txt"
typedef struct book {
 int num;//书刊编号
 char name[50];//书名
 char chuban[50];//出版单位
 int year;//出版时间年
 int month;//出版时间月
 int price;//价格
 char fenlei[10];//书籍分类号
 struct book *next;
}Book;

Book *creat1();//读取文件中的信息存入到链表中
Book *creat2();//手动增加信息创建链表
void output(Book *head);//显示所有结点信息
Book *Delete(Book *head);//删除链表中的一个结点信息
Book *Add(Book *head);//增加结点信息
Book *Sort(Book *head);//排序
void Refer1(Book *head);//输入书名查询结点信息
void Refer2(Book *head);//输入出版单位查询结点信息
void Refer3(Book *head);//输入书籍分类号查询结点信息
//Book *Update(Book *head);//更新结点信息
void Save(Book *head);//将链表中的信息保存至文件中

int main()
{
 Book *head;
 int a, b, w = 1;
 while (w)
 {
  printf("*****************************************\n");
  printf("*       图书期刊信息管理系统            *\n");
  printf("*        1.书籍信息录入(从文件中读取).  *\n");
  printf("*        2.书籍信息录入(手动增加).      *\n");
  printf("*****************************************\n");
  scanf("%d", &a);
  if (a == 1)
  {
   head = creat1(); w = 0;
  }
  else if (a == 2)
  {
   head = creat2();
   head=Sort(head);
   w = 0;
  }
  else  break;
 }
 while (1)
 {
  system("cls");
  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");
  scanf("%d", &b);
  switch (b)
  {
  case 1:
   head = Add(head);
   head = Sort(head);
   system("pause");
   break;
  case 2:
   head = Delete(head);
   system("pause");
   break;
  case 3:
   output(head);
   system("pause");
   break;
  case 4:
   Refer1(head);
   system("pause");
   break;
  case 5:
   Refer2(head);
   system("pause");
   break;
  case 6:
   Refer3(head);
   system("pause");
   break;
  case 7:
   Save(head);
   return 0;
  default:
   printf("输入的信息错误,请重新输入!\n");
   break;
  }
 }
 return 0;
}

Book *creat1()//读取文件中的信息存入到链表中
{
 FILE *fp;
 int k = 0; Book st, *p, *p0 = NULL, *head = NULL;
 fp = fopen(filename, "r");
 if (fp == NULL)
 {
  printf("打开文件失败!\n");
  exit(0);
 }
 while (!feof(fp))
 {
  fscanf(fp, "%d%s%s%d%d%d%s", &st.num, st.name, st.chuban, &st.year, &st.month, &st.price, st.fenlei);
  p = (Book *)malloc(sizeof(Book));
  *p = st;
  (*p).next = NULL;
  if (p0 == NULL)
  {
   head = p; p0 = p;
  }
  else {
   (*p0).next = p; p0 = p;
  }
 }
 fclose(fp);
 printf("录入成功!\n");
 system("pause");
 return head;
}

Book *creat2()//手动增加信息创建链表
{
 Book *p, *head = NULL, *p0 = NULL;
 Book pnew;
 Book *q = head;
 char ch;
 int w = 1;
 while (w)
 {
  printf("请输入增加的书籍信息\n");
  printf("书刊编号:");
  scanf("%d", &pnew.num);
  printf("书名:");
  scanf("%s", pnew.name);
  printf("出版单位:");
  scanf("%s", pnew.chuban);
  printf("出版时间:");
  scanf("%d%d", &pnew.year, &pnew.month);
  printf("价格:");
  scanf("%d", &pnew.price);
  printf("书籍分类:");
  scanf("%s", pnew.fenlei);
  while (q!= NULL)//
  {
   if ((*q).num == pnew.num)
   {
    printf("您输入的书籍信息已经存在!请重新输入\n");
    system("pause");
    break;
   }
   q = (*q).next;
  }
  if (q != NULL)continue;
  else{
  p = (Book *)malloc(sizeof(Book));
  *p = pnew;
  (*p).next = NULL;
  if (p0 == NULL)
  {
   head = p; p0 = p;
  }
  else {
   (*p0).next = p; p0 = p;
  }
  printf("插入成功!\n");
  printf("是否继续插入(Y/N)");
  scanf("\n%c", &ch);
  if (ch =='N' || ch == 'n')
   w = 0;
  }
 }
 return head;
}

void Save(Book *head)//将链表中的信息保存至文件中
{
 Book *p = head;
 FILE *fp;
 fp = fopen(filename, "w");
 if (fp == NULL)
 {
  printf("打开文件失败!\n");
  exit(0);
 }
 while ((*p).next != NULL)
 {
  fprintf(fp, "%d\t%s\t%s\t%d\t%d\t%d\t%s\n", (*p).num, (*p).name, (*p).chuban, (*p).year, (*p).month, (*p).price, (*p).fenlei);
  p = (*p).next;
 }
 fprintf(fp, "%d\t%s\t%s\t%d\t%d\t%d\t%s", (*p).num, (*p).name, (*p).chuban, (*p).year, (*p).month, (*p).price, (*p).fenlei);
 fclose(fp);
}

void output(Book *head)
{
 Book *p = head;
 if (p != NULL)
 {
  printf("所有图书信息如下:\n");
  printf("编号\t书名\t出版单位\t出版时间\t价格\t书籍分类\n");
  do {
   printf("%d\t%10s\t%10s\t%d-%d\t%d\t%s\n", (*p).num, (*p).name, (*p).chuban, (*p).year, (*p).month, (*p).price, (*p).fenlei);
   p = (*p).next;
  } while (p != NULL);
  printf("\n");
 }
 else printf("书籍信息为空!\n");
}
Book* Delete(Book *head)//删除链表中的一个结点信息
{
 Book *p = head, *p0 = NULL;
 int n;
 printf("请输入要删除的书刊编号:");
 scanf("%d", &n);
 while (p)
 {
  if ((*p).num == n)
  {
   if (p == head)head = (*p).next;
   else if ((*p).next == NULL)(*p0).next = NULL;
   else (*p0).next = (*p).next;
   free(p);
   break;
  }
  else
  {
   p0 = p;
   p = (*p).next;
  }
 }
 if (p == NULL)printf("找不到信息!\n");
 else printf("删除成功!\n");
 return head;
}
//
Book* Add(Book *head)//增加结点信息
{
 Book *p = head;
 Book *pnew;
 Book *q= head;
 int w = 1;
 while (w)
 {
  pnew = (Book*)malloc(sizeof(Book));
  printf("请输入增加的书籍信息\n");
  printf("书刊编号:");
  scanf("%d", &(*pnew).num);
  printf("书名:");
  scanf("%s", (*pnew).name);
  printf("出版单位:");
  scanf("%s", (*pnew).chuban);
  printf("出版时间:");
  scanf("%d%d", &(*pnew).year, &(*pnew).month);
  printf("价格:");
  scanf("%d", &(*pnew).price);
  printf("书籍分类:");
  scanf("%s", (*pnew).fenlei);
  while (q != NULL)//遍历链表,若插入的信息已经存在,则退出
  {
   if ((*q).num == (*pnew).num)
   {
    printf("您输入的书籍信息已经存在!");
    system("pause");
    return head;
   }
   q = (*q).next;
  }
  if ((*p).next != NULL){
   while ((*p).next != NULL)//让尾指针循环直到最后一个结点
    p = (*p).next;
   }
  p->next = pnew;
   p = pnew;
   p->next = NULL;
   printf("插入成功!\n");
    w = 0;
 }
 return head;
}
//选择排序,交换结点
Book* Sort(Book *head)//排序
{
 Book *begin = NULL, *end = NULL;//链表的首尾结点指针
 Book *p;
 Book *min, *premin;//最小结点及其前一个结点
 if (!head)return NULL;
 while (head) {
  //循环找出链表中的最小结点
  p = head;
  min = p;
  while ((*p).next != NULL) {
   if (strcmp((*min).name, (*(*p).next).name) > 0) {
    premin = p;
    min = (*p).next;
   }
   p = p->next;
  }
  //将min放进有序链表
  if (begin == NULL)
  {
   begin = end = min;
  }
  else {
   (*end).next = min;
   end = min;
  }
  //在无序链表中删除min
  if (min == head) {
   head = (*min).next;
  }
  else {
   (*premin).next = (*min).next;
  }
 }
 (*end).next = NULL;
 return begin;
}

void Refer1(Book *head)
{
 Book *p = head;
 char ch[10];
 int flag = 0;
 printf("请输入待查询的内容:");
 scanf("%s", ch);
 printf("查询到的信息如下;\n");
 printf("编号\t书名\t出版单位\t出版时间\t价格\t书籍分类\n");
 while (p != NULL)
 {
  char *res; int a;
  res = (char*)memchr((*p).name, ch[0], strlen((*p).name));  //根据要查找的字符串第一个字符,切割源字符串
  if (res != NULL)
  {
   a = memcmp(res, ch, strlen(ch)); //比较
   if (a == 0)
   {
    printf("%d\t%10s\t%10s\t%d-%d\t%d\t%s\n", (*p).num, (*p).name, (*p).chuban, (*p).year, (*p).month, (*p).price, (*p).fenlei);
    flag++;
   }
  }
  p = (*p).next;
 }
 if (flag > 0) printf("共有%d条记录!\n", flag);
 else printf("无任何结果!\n");
}

void Refer2(Book *head)
{
 Book *p = head;
 char ch[10];
 int flag = 0;
 printf("请输入待查询的内容:");
 scanf("%s", ch);
 printf("查询到的信息如下;\n");
 printf("编号\t书名\t出版单位\t出版时间\t价格\t书籍分类\n");
 while (p != NULL)
 {
  char *res; int a;
  res = (char*)memchr((*p).chuban, ch[0], strlen((*p).chuban));  //根据要查找的字符串第一个字符,切割源字符串
  if (res != NULL)
  {
   a = memcmp(res, ch, strlen(ch)); //比较
   if (a == 0)
   {
    printf("%d\t%10s\t%10s\t%d-%d\t%d\t%s\n", (*p).num, (*p).name, (*p).chuban, (*p).year, (*p).month, (*p).price, (*p).fenlei);
    flag++;
   }
  }
  p = (*p).next;
 }
 if (flag > 0) printf("共有%d条记录!\n", flag);
 else printf("无任何结果!\n");
}

void Refer3(Book *head)
{
 Book *p = head;
 char ch[10];
 int flag = 0;
 printf("请输入待查询的内容:");
 scanf("%s", ch);
 printf("查询到的信息如下;\n");
 printf("编号\t书名\t出版单位\t出版时间\t价格\t书籍分类\n");
 while (p != NULL)
 {
  char *res; int a;
  res = (char*)memchr((*p).fenlei, ch[0], strlen((*p).fenlei));  //根据要查找的字符串第一个字符,切割源字符串
  if (res != NULL)
  {
   a = memcmp(res, ch, strlen(ch)); //比较
   if (a == 0)
   {
    printf("%d\t%10s\t%10s\t%d-%d\t%d\t%s\n", (*p).num, (*p).name, (*p).chuban, (*p).year, (*p).month, (*p).price, (*p).fenlei);
    flag++;
   }
  }
  p = (*p).next;
 }
 if (flag > 0) printf("共有%d条记录!\n", flag);
 else printf("无任何结果!\n");
}

运行结果

读取数据
可以从文件中读取,也可以自己手动输入
在这里插入图片描述
从文件中读取数据创建链表
测试程序的增加节点功能
在这里插入图片描述
测试程序的浏览功能,可以看到上一个图增加的结点信息!在这里插入图片描述
测试函数的删除功能
在这里插入图片描述
删除之后再进行浏览,可以看到结点信息已被删除在这里插入图片描述
测试函数的查询功能
输入内容,可以找出含有该内容的信息。
按书名来查询信息
在这里插入图片描述
按出版社来查询信息
在这里插入图片描述
按书籍分类号来查询信息
在这里插入图片描述

  • 11
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值