栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++实现简单图书馆

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++实现简单图书馆

用C++写一个小型图书馆系统,要求功能:
1.在控制台打印现有书单。
2.录入新书。
3.删除书籍。
4.将现有书单写入TXT文件。
5.从TXT文件读入书单。
6.按不同要求排序书籍。
7.找到书名最长的书。

由于这是大一上学期的期末作业,并没有学到链表,甚至连类都没有学,只能用结构体数组实现书单。

#define MAXLENAUTHOR 40//作者名长度限制
#define MAXLENBOOK 50//书名长度限制
enum Categbook { Science_Fiction, Fiction, Classic };//书籍的类型
int capacity = 6;//数组大小
int numbook = 5;//书籍数量
struct BOOK { bool tag = false; 
char author[MAXLENAUTHOR] = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz";
 char title[MAXLENBOOK]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"; 
int year = 2019; double price = 99999999.0; Categbook category=Science_Fiction; };

上面是一些基础的变量和书籍结构体。

在这里我用tag标记书籍,tag为true代表书存在。为的就是删除书籍的时候不用重新new一个动态数组,但这样偷懒的举动给我带来了很多的麻烦。所有变量初始化时为了方便排序。还有就是我在数组大小和书本数量上用了全局变量,其实可以把他们写进一个新结构体中,比如:

struct BOOKLIST {int capacity;int numbook;BOOK *booklist;};

然后,我们建立一个BOOK类型的动态数组,并写一个switch函数

 BOOK *booklist = new BOOK[capacity];
 char in;
    while(1)
    {   
 mainjiemian();
 cin >> in;
 switch (in) {
 case'1':
     bookinfo(booklist);
     system("cls");
     break;
 case'2':
     addbook(booklist);
     system("cls");
     break;
 case'3':
     delbook(booklist);
     system("cls");
     break;
 case'4':
     write(booklist);
     system("cls");
     break;
 case'5':
     read(booklist);
     system("cls");
     break;
 case'6':
     system("cls");
     sortbook(booklist);
     system("cls");
     break;
 case'7':
     findbook(booklist);
     system("cls");
     break;
 case'8':
     delete[]booklist;//退出程序前一定要delete掉动态数组
     exit(0);
 case'9':
     system("cls");
     inibook(*&booklist);
     system("cls");
     break;
 default:cout << "Illegal input" << endl;
 }
    }

然后就开始按照switch来一步步写函数了:

  • 检查数组是否满容
void examination(BOOK *&booklist)
{
    if (capacity == numbook)
    {
 printf("Began to expand the array.n");
 BOOK *newbooklist = new BOOK[capacity + addsize];

 for (int i = capacity; i < (capacity+addsize); i++) {
     newbooklist[i].tag = false;  
     numbook = 0;
 }
 for (int i = 0; i < capacity; i++) {
     if (booklist[i].tag == true) {
  newbooklist[i] = booklist[i];
  numbook++;
     }
 }
 delete[]booklist;//删除旧指针指向的空间
 capacity = capacity + addsize;
 booklist = newbooklist;//将指针指向新分配的空间
 newbooklist = nullptr;
    }
}
  • 初始化书单
void inibook(BOOK *&booklist)
{
    for (int i = 0; i < (capacity); i++) {
 booklist[i].tag = false;//所有书籍的标记为false
 numbook = 0;
    }
}
  • 打印书单
void bookinfo(BOOK *&booklist)
{
    printf("nnumbook: %dncapacity: %dn",numbook,capacity);
    for (int i = 0; i < capacity; i++) {
 if (booklist[i].tag == true) {
     printf("nThe number of the book is: %d", i);
     printf("nTitle: %snAuthor: %snCategory: %snYear  of release: %dnPrice: %.2f YUANn", booklist[i].title, booklist[i].author, categoryStrings[booklist[i].category], booklist[i].year, booklist[i].price);
 }
    }
    system("pause");
}
  • 删除书籍
void delbook(BOOK *&booklist)
{
    if (numbook < 1) {
 printf("There is no book in the booklist!n");
    }
    else {
 int i;
 printf("nPlease input the number of book you want to delete:");
 scanf("%d", &i);
 if (i > capacity) {
     printf("This book does not exist!n");
 }
 else {
     booklist[i].tag = false;
     numbook--;
 }
    }

    system("pause");
}

此处应当做两个判断:书柜中是否有书和要删除的书是否存在。

  • 录入新书
void addbook(BOOK *&booklist)
{
    int i;  
    for ( i = 0; i < capacity; i++) {
 if (booklist[i].tag == false) {
     break;
 }
    }
    printf("nINFORMATIONS FOR THE BOOKnn");      

    printf("The number of the book you are about to add is: %dn", i);
    booklist[i].tag = true;     
    char bookname[MAXLENBOOK];
    printf("Please input the name of the book:");

    scanf("%s", bookname);
    getchar();
    sprintf_s(booklist[i].title, MAXLENBOOK, "%s", bookname);

    char authorname[MAXLENAUTHOR];
    printf("Please input the name of the author:");
    scanf("%s", authorname);
    getchar();
    sprintf_s(booklist[i].author, MAXLENAUTHOR, "%s", authorname);

    int year = 0;
    while (1)
    {
 printf("Please input the year of release:");
 scanf("%d", &year);
 getchar();
 if (year < -5000 || year>2018)
 {
 printf("nYour input is illegal.Try again.n");
 }
 else
 {
     booklist[i].year = year;
     break;
 }
    }

    float price = 0.0;
    while (1)
    {
    printf("Please input the price of the book:");
    scanf("%f", &price);
    getchar();
    if (price < 0)
    {printf("nYour input is illegal.Try again.");}
    else
    {booklist[i].price = price;
 break;}
    }

    int categ;
    while (1)
    {
 printf("n");
 for (int i = 0; i < sizeof(categoryStrings) / sizeof(categoryStrings[0]); i++)
 {
     printf("n%d.%s", i + 1, categoryStrings[i]);
 }
 printf("nPlease input the number of  category of the book:");
 scanf("%d", &categ);
 getchar();
 if (categ<1 || categ> sizeof(categoryStrings) / sizeof(categoryStrings[0]))
 {
     printf("nYour input is illegal.Try again.");
 }
 else
    {
     booklist[i].category = (Categbook)(categ - 1);
     break;
     }
    }
    numbook++;

    printf("nnENDn");
    examination(booklist);
    system("pause");
}
  • 排序函数
    void sortbook(BOOK *&booklist)
    {
    if (numbook < 2) {
        printf("No need to sort!n");
        system("pause");
    }
    else {
        char ins;
        while (1)
        {
     sortjiemian();
     cin >> ins;
     switch (ins) {
     case'1':
         for (int i = 0; i < capacity; i++) {
      int m = i;
      for (int j = i + 1; j < capacity; j++) {
          if (CmpStr(booklist[m].author, booklist[j].author) > 0) {
       m = j;
          }
      }
      if (i != m) {
          Swapbook(booklist[i], booklist[m]);
      }
         }
         printf("Sorted booklist is:");
         bookinfo(booklist);
         break;
     case'2':
         for (int i = 0; i < capacity; i++) {
      int m = i;
      for (int j = i + 1; j < capacity; j++) {
          if (CmpStr(booklist[m].title, booklist[j].title) > 0) {
       m = j;
          }
      }
      if (i != m) {
          Swapbook(booklist[i], booklist[m]);
      }
         }
         printf("Sorted booklist is:");
         bookinfo(booklist);
         break;
     case'3':
         for (int i = 0; i < capacity; i++) {
      int m = i;
      for (int j = i + 1; j < capacity; j++) {
          if (CmpInt(booklist[m].year, booklist[j].year) > 0) {
       m = j;
          }
      }
      if (i != m) {
          Swapbook(booklist[i], booklist[m]);
      }
         }
         printf("Sorted booklist is:");
         bookinfo(booklist);
         break;
     case'4':
         for (int i = 0; i < capacity; i++) {
      int m = i;
      for (int j = i + 1; j < capacity; j++) {
          if (CmpFloat(booklist[m].price, booklist[j].price) > 0) {
       m = j;
          }
      }
      if (i != m) {
          Swapbook(booklist[i], booklist[m]);
      }
         }
         printf("Sorted booklist is:");
         bookinfo(booklist);
         break;
     case'5':
         for (int i = 0; i < capacity; i++) {
      int m = i;
      for (int j = i + 1; j < capacity; j++) {
          if (CmpInt(booklist[m].category, booklist[j].category) < 0) {
       m = j;
          }
      }
      if (i != m) {
          Swapbook(booklist[i], booklist[m]);
      }
         }
         printf("Sorted booklist is:");
         bookinfo(booklist);
         break;
     case'6':
         mainjiemian();
         break;
     default:cout << "Illegal input" << endl;
     }
     break;
        }
    }
    mainjiemian();

}

int CmpStr(char pp1, char pp2)//比较两个字符串长度
{
int nResult;
char pa, pb, a, b;
pa = pp1;
pb = pp2;
do
{
a = pa;
b = pb;
pa++;
pb++;
} while ((a == b) && (a != 0) && (b != 0));
nResult = a - b;
return nResult;
}
void Swapbook(BOOK& book1, BOOK& book2)//交换函数
{
BOOK temp = book1;
book1 = book2;
book2 = temp;
}
int CmpInt(int a, int b)//比较两个int类型变量
{
return a - b;
}
int CmpFloat(float a, float b)//比较两个float类型变量
{
int nResult;
if (a - b > 0)
{ nResult = 1;}
if ( a - b < 0)
{ nResult = -1;}
if ( a - b == 0.0)
{ nResult = 0;}
return nResult;
}

老师希望我们把排序函数写成一个,只需要传递不同的参数就可以对所有项目排序,但是那样要多写好几个函数,而且实现起来效果差不多,所以我只写了比较函数和交换函数(其实是嫌麻烦不想写)。

这里还要加一个判断,如果书柜中书记数量小于1,那么就不需要排序。

 - 找出书名最长的书

void findbook(BOOK *booklist)
{
int j = 0;
int n = 0;
char*a = new char[capacity];
for (int q = 0; q < capacity; q++) {
a[q] = new char[MAXLENBOOK];
}
for (int i = 0; i < capacity; i++) {
if (booklist[i].tag == 1) {
sprintf_s(a[j], MAXLENBOOK, "%s", booklist[i].title);
j++;
}
}
for (int z = 0; z < j; z++) {
charptr1 = a[z];
charptr2 = a[n];
if (strlen(ptr1) > strlen(ptr2)) {
n = z;
}
}

for (int i = 0; i < j; i++) {
    char*ptr1 = a[n];
    char*ptr2 = a[i];
    if (strlen(ptr1) == strlen(ptr2)) {
 printf("The book with the longest name is:%s.n", a[i]);
    }
}
for (int p = 0; p < capacity; p++)
    delete[] a[p];
delete[] a;
system("pause");

}

我将所有书名写入一个新数组再比较他们的长度,找到最长的那一个。我觉得这是个效率很低的方法,但想不出其他方法了。

我考虑到可能会有同名书籍的存在,于是加了一个循环。

 - 将书单写入TXT文件和从TXT中读取

void write(BOOK &booklist)
{
FILE fp = NULL;

if (NULL == (fp = fopen("lab6.txt", "w")))
{
    printf("error");
}
else {
    for (int i = 0; i < capacity; i++) {
 if (booklist[i].tag == true) {
     BOOK book = booklist[i];
     fprintf(fp, "Title: %snAuthor: %snCategory: %dnYear of release: %dnPrice: %lf YUANn", book.title, book.author, book.category, book.year, book.price);
 }
    }
}
fclose(fp);
printf("Succeed!n");
system("pause");

}

void read(BOOK *&booklist)
{
inibook(booklist);

FILE *fp = NULL;
if (NULL == (fp = fopen("lab6.txt", "r")))
{
    printf("Error");
}
else {
    int i = 0;
    numbook = 0;
    while (!feof(fp)) 
    {
 fscanf(fp, "Title: n%[^n]nAuthor: n%[^n]nCategory: %dnYear of release: %dnPrice: %lf YUANn", &booklist[i].title, &booklist[i].author, &booklist[i].category, &booklist[i].year, &booklist[i].price);
 booklist[i].tag = true;
 numbook++;
 i++;
 examination(booklist);      
    }
}
fclose(fp);
printf("Succeed!n");
system("pause");

}

讲道理这两个都是按格式写就会没问题的函数,但是,write函数很好很ok,但read函数各种不合作,根本不工作。在我苦思冥想之后,终于发现问题是出在“%s”上。“%s”在读取时遇到空格或者空行就会停止读取,导致整个函数无法按照正确的预设的格式读取。情况就是:文件也正常打开了,指针也没问题,就是一直读啊读,没个完。

最后我用了“n%[^n]”这个指令来读取整行字符。网上推荐的"%[^n]%*c"指令好像在我的程序不起作用

 - 界面函数

void mainjiemian()
{
cout << "" << endl;
cout << " library " << endl;
cout << " " << endl;
cout << " (1) Show existing books" << endl;
cout << " " << endl;
cout << " (2) Add a new book " << endl;
cout << " " << endl;
cout << " (3) Delete book(s) " << endl;
cout << " " << endl;
cout << " (4) Write the books to the file " << endl;
cout << " " << endl;
cout << " (5) Read the books from the file " << endl;
cout << " " << endl;
cout << " (6) Sort books " << endl;
cout << " " << endl;
cout << " (7) Find the book with the longest name " << endl;
cout << " " << endl;
cout << " (8) Exit " << endl;
cout << "
" << endl;
cout << "Please select an option:" << endl;
}
void sortjiemian()
{
cout << "**" << endl;
cout << " Sort options " << endl;
cout << "" << endl;
cout << " (1) Sort by author" << endl;
cout << "" << endl;
cout << " (2) Sort by name " << endl;
cout << "" << endl;
cout << " (3) Sort by year " << endl;
cout << "" << endl;
cout << " (4) Sort by price " << endl;
cout << "" << endl;
cout << " (5) Sort by category " << endl;
cout << "" << endl;
cout << " (6) exit " << endl;
cout << "**" << endl;
cout << "Please select an option:" << endl;
}

最后就是和switch配套的两个界面函数了。

现在想想这个程序也不是很难,但在做的过程中各种层出不穷奇奇怪怪的BUG、报错都曾搞得我焦头烂额。最后做完时感到的是如释重负而不是大功告成的开心。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/232832.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号