C语言课设——图书信息管理系统
其實這個題目要實現(xiàn)的功能比較清晰,主要就是文件和鏈表的操作以及基于這兩個基礎上的填刪改查等功能,當然也可以添加一些個性化的功能,比如按照圖書的檢索量來對庫存的圖書進行熱度的排序。
以下是我的這個圖書管理系統(tǒng)的功能圖以及菜單之間的調(diào)用情況(兩張圖基本一樣,第二張圖顯示了菜單的調(diào)用信息)
?
?
附上源碼,有好的建議歡迎各位指正!
第二部分的代碼是一個頭文件,里邊包含了我需要用的的頭文件以及三大部分關鍵函數(shù)的函數(shù)體,第一個是創(chuàng)建鏈表存入數(shù)據(jù)并返回頭指針,第二個是將鏈表放入相應的文件,第三個是將數(shù)據(jù)從文件中取出并形成新的鏈表。(Book,Administrator,Reader三個結構體各有一套函數(shù))
在實際編程的過程中碰到一些問題,和大家分享一下:
1、讀者,管理員,書籍三者基礎數(shù)據(jù)(至少100條)的錄入,最初我采用的方法是只用一個函數(shù)將創(chuàng)建鏈表節(jié)點以及將節(jié)點數(shù)據(jù)存入文件,后來在編寫其他功能時由于多次用到將鏈表數(shù)據(jù)從文件取出建立鏈表以及將修改后的鏈表數(shù)據(jù)存回文件的操作,我就將原來的一個函數(shù)拆分成三個相對獨立的函數(shù),分別是Create創(chuàng)建基礎數(shù)據(jù)的鏈表并返回頭指針,Save將鏈表數(shù)據(jù)存入相應文件(參數(shù)為鏈表頭指針),List將數(shù)據(jù)從文件中取出放在新建立的鏈表并返回鏈表的頭指針;
2、在寫到讀者借書還書的功能時,由于牽涉到要修改讀者的相關信息,你們就會涉及到登錄操作,當因為我的登錄函數(shù)沒有返回值(void),因此如果要完整的實現(xiàn)整個功能的話就需要將登錄程序原封不動的再寫一遍,因此我直接將登錄程序的返回值寫成struct Reader/Administrator *p類型,將登錄者本人的節(jié)點的頭指針返回,這樣可以再借書還書程序中直接調(diào)用。這樣還有一個好處,就是模擬了登錄的真實過程:登陸后可以直接對個人的數(shù)據(jù)進行操作和保存,不用每次都要輸入用戶名和密碼進行匹配,使程序邏輯更流暢;
3、我在遍歷鏈表打印不管是讀者亦或是書籍信息的時候會多輸出一行亂碼數(shù)據(jù),然后我就在List函數(shù)的while循環(huán)那里設置斷點查看循環(huán)的情況,后來發(fā)現(xiàn)循環(huán)比我預想的多進行了一次,導致在文件數(shù)據(jù)已經(jīng)全部儲存到鏈表之后又多創(chuàng)建了一個節(jié)點,然而該節(jié)點李并未存入任何實質(zhì)性的數(shù)據(jù)。在深究為什么會多出一次循環(huán)的時候我發(fā)現(xiàn)自己似乎對文件位置標記的理解并不是很清楚,我的while循環(huán)的條件是(!feof(fp)),我最初認為當我創(chuàng)建完最后一個節(jié)點并將文件數(shù)據(jù)存進去之后由于此時文件位置標記已經(jīng)移到了最后所以會少執(zhí)行一次“將最后兩個節(jié)點鏈起來”的操作,因此我在循環(huán)中加了一個if語句,即if(feof(fp)),之后將執(zhí)行那個被跳過的操作。由于前面已經(jīng)證實循環(huán)在文件到達末尾之后似乎還會在進行一次循環(huán),所以if語句就顯得沒有必要,因此我在去掉if語句之后果然輸出正常。但這不禁讓我更加疑問,文件位置標記在執(zhí)行完一次fread后到底如何移動?
4、我在輸出的過程中也遇到了segmentation fault也就是段錯誤,在查找了相關博客之后我發(fā)現(xiàn)自己段錯誤的原因是指針訪問了非法內(nèi)存,具體到我的程序中就是我在遍歷鏈表的過程中讓指針多向后移動了一個位置,但那個位置指向的內(nèi)容是不可預知的,因此就出錯了。后來我發(fā)現(xiàn)在遍歷鏈表的過程中用一個指針反而比兩個指針更簡潔有效,因此我就將遍歷鏈表的那個循環(huán)改成了while(p!=NULL){…p = p->next};修改完之后沒有再出現(xiàn)段錯誤;
5、在打印讀者、管理員、和書籍相關信息時的排版問題,由于這些字符串的長度各不相同,因此在打印時容易出現(xiàn)錯位的現(xiàn)象;解決辦法:對于長度較短的讀者和管理員的相關數(shù)據(jù)采用\t進行修正,對于書名和作者名比較長的書籍數(shù)據(jù)來說采用指定域?qū)挼姆绞竭M行對齊,如%25s。
#include"Create & Save.h"void menu1(); void menu2(); void menu3(); void menu4(); void menu5(struct Administrator *p); void menu6(); void menu7(struct Reader *p); void menu8(); void menu9(); void menu10(); void reader_Register(); //讀者注冊 void administrator_Register(); //管理員注冊 struct Reader *reader_Log(); //讀者登錄 struct Administrator *administrator_Log(); //管理員登錄 void reader_Change(struct Reader *p); //讀者信息修改 void administrator_Change(struct Administrator *p); //管理員信息修改 void book_Research(); //圖書查詢 void book_Add(); //圖書添加 void book_Delete(); //圖書刪除 void book_Change(); //圖書信息修改 void reader_Print(); //讀者信息一覽表 void administrator_Print(); //管理員信息一覽表 void book_TopN(int N); //圖書Top(按照檢索量排名) void reader_bPrint(struct Reader *p); //讀者借閱信息一覽表 void reader_Borrow(struct Reader *p); //借閱功能 void reader_Return(struct Reader *p); //還書功能int N1=125; //圖書數(shù)量 int N2=125; //讀者數(shù)量 int N3=20; //管理員數(shù)量int main() {// printf("錄入書籍數(shù)據(jù)(書名 ISBN號 作者 庫存量 余量 檢索量)\n");// struct Book *head3;// head3 = book_Create(N1);// book_Save(head3);// printf("錄入管理員數(shù)據(jù)(用戶名 密碼)\n");// struct Administrator *head2;// head2 = administrator_Create(N3);// administrator_Save(head2);// printf("錄入讀者數(shù)據(jù)(用戶名 密碼 借閱本數(shù) 書名 ISBN 作者 庫存 余量 檢索量)\n");// struct Reader *head1;// head1 = reader_Create(N2);// reader_Save(head1);// printf("\n3s后跳轉(zhuǎn)至主菜單\n");// Sleep(3000);menu1();system("pause");return 0; }void menu1() {system("cls");int i;printf("**********************************************************\n");printf("**\t\t歡迎使用圖書管理系統(tǒng)V1.1\t\t**\n");printf("**********************************************************\n");printf("\n**\t\t\t1.登錄系統(tǒng)\t\t\t**\n");printf("\n**\t\t\t2.圖書系統(tǒng)\t\t\t**\n");printf("\n**\t\t\t3.退出系統(tǒng)\t\t\t**\n");printf("\n**********************************************************\n\n");printf("請選擇功能:");scanf("%d",&i);switch(i) {case 1: menu2();//登陸系統(tǒng)break;case 2: menu8();//圖書信息break;case 3: //退出系統(tǒng)default: {printf("\n退出成功!\n");} break;} }void menu2() {system("cls");int i;printf("**********************************************************\n");printf("**\t\t歡迎使用圖書管理系統(tǒng)V1.1\t\t**\n");printf("**********************************************************\n");printf("\n**\t\t\t1.用戶登錄\t\t\t**\n");printf("\n**\t\t\t2.用戶注冊\t\t\t**\n");printf("\n**\t\t\t3.讀者信息一覽表\t\t**\n");printf("\n**\t\t\t4.管理員信息一覽表\t\t**\n");printf("\n**\t\t\t5.返回上一級\t\t\t**\n");printf("\n**\t\t\t6.退出系統(tǒng)\t\t\t**\n");printf("\n**********************************************************\n\n");printf("請選擇功能:");scanf("%d",&i);switch(i){case 1: menu3();//用戶登錄break;case 2: menu4();//用戶注冊break;case 3: {system("cls");reader_Print();printf("\n按ESC鍵返回上一級!\n");char ch;if((ch=getch())==27){menu2();}} //讀者信息一覽表break;case 4: {system("cls");administrator_Print();printf("\n按ESC鍵返回上一級!\n");char ch;if((ch=getch())==27){menu2();}} //管理員信息一覽表break;case 5: menu1();//返回上一級break;case 6: //退出系統(tǒng)default: {printf("\n退出成功!\n");}break;} }void menu3() {system("cls");int i;printf("**********************************************************\n");printf("**\t\t歡迎使用圖書管理系統(tǒng)V1.1\t\t**\n");printf("**********************************************************\n");printf("\n**\t\t\t1.讀者登錄\t\t\t**\n");printf("\n**\t\t\t2.管理員登錄\t\t\t**\n");printf("\n**\t\t\t3.返回上一級\t\t\t**\n");printf("\n**\t\t\t4.退出系統(tǒng)\t\t\t**\n");printf("\n**********************************************************\n\n");printf("請選擇功能:");scanf("%d",&i);switch(i) {case 1: {struct Reader *p = reader_Log();printf("3s后將自動跳轉(zhuǎn)至讀者功能頁面...\n");Sleep(3000);menu7(p);}break;case 2: {struct Administrator *p1 = administrator_Log();printf("3s后將自動跳轉(zhuǎn)至管理員功能頁面...\n");Sleep(3000);menu5(p1);}//管理員相關break;case 3: menu2();//返回上一級break;case 4: //退出系統(tǒng)default: {printf("\n退出成功!\n");}break;} } void menu4() {system("cls");int i;printf("**********************************************************\n");printf("**\t\t歡迎使用圖書管理系統(tǒng)V1.1\t\t**\n");printf("**********************************************************\n");printf("\n**\t\t\t1.讀者注冊\t\t\t**\n");printf("\n**\t\t\t2.管理員注冊\t\t\t**\n");printf("\n**\t\t\t3.返回上一級\t\t\t**\n");printf("\n**\t\t\t4.退出系統(tǒng)\t\t\t**\n");printf("\n**********************************************************\n");printf("\n請選擇功能:");scanf("%d",&i);switch(i) {case 1: {reader_Register();printf("3s后將自動跳轉(zhuǎn)至登錄頁面...\n");Sleep(3000);struct Reader *p = reader_Log();menu7(p);}//讀者相關break;case 2: {administrator_Register();printf("3s后將自動跳轉(zhuǎn)至登錄頁面...\n");Sleep(3000);struct Administrator *p1 = administrator_Log();menu5(p1);}//管理員相關break;case 3: menu2();//返回上一級break;case 4: //退出系統(tǒng)default:{printf("\n退出成功!\n");} break;} } void menu5(struct Administrator *p) {system("cls");int i;printf("**********************************************************\n");printf("**\t\t歡迎使用圖書管理系統(tǒng)V1.1\t\t**\n");printf("**********************************************************\n");printf("\n**\t\t\t1.圖書添加\t\t\t**\n");printf("\n**\t\t\t2.圖書刪除\t\t\t**\n");printf("\n**\t\t\t3.圖書信息修改\t\t\t**\n");printf("\n**\t\t\t4.修改個人信息\t\t\t**\n");printf("\n**\t\t\t5.返回上一級\t\t\t**\n");printf("\n**\t\t\t6.退出系統(tǒng)\t\t\t**\n");printf("\n**********************************************************\n");printf("\n請選擇功能:");scanf("%d",&i);switch(i) {case 1: { //圖書添加book_Add();printf("\n請按ESC鍵返回上一級!\n");char ch;if((ch=getch())==27){menu5(p);}}break;case 2: {book_Delete();printf("\n請按ESC鍵返回上一級!\n");char ch;if((ch=getch())==27){menu5(p);}} //圖書刪除break;case 3: {menu6();book_Change(p);printf("\n請按ESC鍵返回上一級!\n");char ch;if((ch=getch())==27){menu5(p);}} //圖書信息修改break;case 4: {menu10();administrator_Change(p);printf("3s后將自動跳轉(zhuǎn)至登錄頁面,請重新登錄...\n");Sleep(3000);struct Administrator *p1 = administrator_Log();menu5(p1);} //修改個人信息break;case 5: menu3(); //返回上一級break;case 6:default: printf("退出成功!\n");break;} }void menu6() {system("cls");printf("**********************************************************\n");printf("**\t\t歡迎使用圖書管理系統(tǒng)V1.1\t\t**\n");printf("**********************************************************\n");printf("\n**\t\t\t1.ISBN號修改\t\t\t**\n");printf("\n**\t\t\t2.作者修改\t\t\t**\n");printf("\n**\t\t\t3.庫存量修改\t\t\t**\n");printf("\n**\t\t\t4.余量修改\t\t\t**\n");printf("\n**\t\t\t5.返回上一級\t\t\t**\n");printf("\n**\t\t\t6.退出系統(tǒng)\t\t\t**\n");printf("**********************************************************\n"); }void menu7(struct Reader *p) //讀者功能菜單 {system("cls");int i;printf("**********************************************************\n");printf("**\t\t歡迎使用圖書管理系統(tǒng)V1.1\t\t**\n");printf("**********************************************************\n");printf("\n**\t\t\t1.圖書借閱\t\t\t**\n");printf("\n**\t\t\t2.圖書歸還\t\t\t**\n");printf("\n**\t\t\t3.查看借閱信息\t\t\t**\n");printf("\n**\t\t\t4.修改個人信息\t\t\t**\n");printf("\n**\t\t\t5.返回上一級\t\t\t**\n");printf("\n**\t\t\t6.退出系統(tǒng)\t\t\t**\n");printf("\n**********************************************************\n");printf("\n請選擇功能:\n");scanf("%d",&i);switch(i){case 1: {reader_Borrow(p);printf("\n請按ESC鍵返回上一級!\n");char ch;if((ch=getch())==27){menu3(); //返回登錄界面借書信息才會更新}} //圖書借閱break;case 2: {reader_Return(p);printf("請按ESC鍵返回上一級!\n");char ch;if((ch=getch())==27){menu3(); //返回登錄界面借書信息才會更新}} //圖書歸還break;case 3: {system("cls");reader_bPrint(p);printf("\n請按ESC鍵返回上一級!\n");char ch;if((ch=getch())==27){menu7(p);}} //查看個人信息case 4: {menu9();reader_Change(p);} //修改個人信息break;case 5: menu3(); //返回上一級break;case 6: //退出系統(tǒng)default: printf("\n退出成功!\n");break;} } void menu8() //圖書系統(tǒng)功能菜單 {system("cls");int i;printf("**********************************************************\n");printf("**\t\t歡迎使用圖書管理系統(tǒng)V1.1\t\t**\n");printf("**********************************************************\n");printf("\n**\t\t\t1.圖書查詢\t\t\t**\n");printf("\n**\t\t\t2.圖書Top_N\t\t\t**\n");printf("\n**\t\t\t3.返回上一級\t\t\t**\n");printf("\n**\t\t\t4.退出系統(tǒng)\t\t\t**\n");printf("\n**********************************************************\n");printf("\n請選擇功能:\n");scanf("%d",&i);switch(i){case 1: {system("cls");book_Research();printf("\n請按ESC鍵返回上一級!\n");char ch;if((ch=getch())==27){menu8();}} //圖書查詢break;case 2: {system("cls");book_TopN(N1);printf("\n請按ESC鍵返回上一級!\n");char ch;if((ch=getch())==27){menu8();}} //圖書Topbreak;case 3: menu1();break;case 4:default: {printf("\n退出成功!\n");} break;} }void menu9() {system("cls");printf("**********************************************************\n");printf("**\t\t歡迎使用圖書管理系統(tǒng)V1.1\t\t**\n");printf("**********************************************************\n");printf("\n**\t\t\t1.用戶名修改\t\t\t**\n");printf("\n**\t\t\t2.用戶密碼修改\t\t\t**\n");printf("\n**\t\t\t3.借閱數(shù)量修改\t\t\t**\n");printf("\n**\t\t\t4.返回上一級\t\t\t**\n");printf("**********************************************************\n"); }void menu10() {system("cls");printf("**********************************************************\n");printf("**\t\t歡迎使用圖書管理系統(tǒng)V1.1\t\t**\n");printf("**********************************************************\n");printf("\n**\t\t\t1.用戶名修改\t\t\t**\n");printf("\n**\t\t\t2.用戶密碼修改\t\t\t**\n");printf("\n**\t\t\t3.返回上一級\t\t\t**\n");printf("**********************************************************\n"); }void reader_Register() //讀者注冊 {FILE *fp;fp = file_Open("Reader.dat","ab");char password[20];struct Reader reader;printf("請輸入用戶名(長度不超過20個字符):\n");scanf("%s",reader.name);while(1){printf("請輸入用戶密碼(長度不超過20個字符):\n");scanf("%s",reader.password);printf("請確認用戶密碼(長度不超過20個字符):\n");scanf("%s",password);if(strcmp(reader.password,password)!=0){printf("兩次密碼不一致,請重新輸入(長度不超過20個字符):\n");}else break;}reader.count = 0; //首次注冊只用收集用戶名和密碼信息,關于書的信息全是空if(fwrite(&reader,len1,1,fp)!=1){printf("file write error\n");return ;}fclose(fp);N2++;printf("恭喜你,注冊成功!\n"); //開始登錄 }void administrator_Register() //管理員注冊 {FILE *fp;fp = file_Open("Administrator.dat","ab");char password[20];struct Administrator administrator;printf("請輸入用戶名(長度不超過20個字符):\n");scanf("%s",administrator.name);while(1){printf("請輸入用戶密碼(長度不超過20個字符):\n");scanf("%s",administrator.password);printf("請確認用戶密碼(長度不超過20個字符):\n");scanf("%s",password);if(strcmp(administrator.password,password)!=0){printf("兩次密碼不一致,請重新輸入(長度不超過20個字符):\n");}else break;}if(fwrite(&administrator,len2,1,fp)!=1){printf("file write error\n");}fclose(fp); //開始登錄N3++;printf("恭喜你,注冊成功!\n"); }struct Reader *reader_Log() //讀者登錄 需要返回一個Reader結構體指針,以便我接下來借書還書時使用 {struct Reader *head=reader_List("rb"); //將文件數(shù)據(jù)取出來重新構建鏈表struct Reader *p;struct Reader reader;while(1){int flag=1;printf("請輸入用戶名:\n");scanf("%s",reader.name);printf("請輸入用戶密碼:\n");scanf("%s",reader.password);p = head;while(p!=NULL){if(strcmp(p->name,reader.name)==0){if(strcmp(p->password,reader.password)==0){printf("登錄成功!\n");break;}}if(p !=NULL){p = p->next;}}if(p==NULL){printf("用戶名或密碼錯誤,請重新輸入!\n");flag = 0;}if(flag) break;}return p; }void reader_Change(struct Reader *p) //讀者信息修改 {struct Reader *head = reader_List("rb");struct Reader *p1;p1 = head;while(p1!=NULL){if(strcmp(p1->name,p->name)==0){int i;printf("請選擇相應的修改項:\n");scanf("%d",&i);switch(i){case 1: {printf("請輸入修改后的用戶名:\n");scanf("%s",p1->name);} break;case 2: {printf("請輸入修改后的用戶密碼:\n");scanf("%s",p1->password);} break;case 3: {printf("請輸入修改后的借閱數(shù)量:\n");scanf("%d",&p1->count);} break;case 4: menu7(p);//返回上一級 這里在返回時有bug,明天改break;default: break;}reader_Save(head);if(i==1||i==2||i==3){printf("讀者信息修改成功!\n");printf("3s后將自動跳轉(zhuǎn)至登錄頁面,請重新登錄...\n");Sleep(3000);struct Reader *p2 = reader_Log();menu7(p2);}break;}p1 = p1->next; //簡化遍歷過程,不要用p2指針,容易亂}if(p1==NULL){printf("讀者信息不存在!\n");} }struct Administrator *administrator_Log() //管理員登錄 {struct Administrator *head=administrator_List("rb"); //將文件數(shù)據(jù)取出來重新構建鏈表struct Administrator *p;struct Administrator administrator;while(1){int flag=1;printf("請輸入用戶名:\n");scanf("%s",administrator.name);printf("請輸入用戶密碼:\n");scanf("%s",administrator.password);p = head;while(p!=NULL){if(strcmp(p->name,administrator.name)==0){if(strcmp(p->password,administrator.password)==0){printf("登錄成功!\n"); //注意break的位置,語句別放錯了break;}}if(p != NULL){p = p->next;}}if(p==NULL){printf("用戶名或密碼錯誤,請重新輸入!\n");flag = 0;}if(flag) break;}return p; }void administrator_Change(struct Administrator *p) //管理員信息修改 {struct Administrator *head = administrator_List("rb");struct Administrator *p1;p1 = head;while(p1!=NULL){if(strcmp(p1->name,p->name)==0){int i;printf("請選擇相應的修改項:\n");scanf("%d",&i);switch(i){case 1: {printf("請輸入修改后的用戶名:\n");scanf("%s",p1->name);} break;case 2: {printf("請輸入修改后的用戶密碼:\n");scanf("%s",p1->password);} break;case 3: menu5(p);break; //返回上一級default: break;} printf("管理員信息修改成功!\n");break;}p1 = p1->next; //簡化遍歷過程,不要用p2指針,容易亂}if(p1==NULL){printf("管理員信息不存在!\n");}administrator_Save(head); }void book_Add() //圖書添加函數(shù) {FILE *fp;fp = file_Open("Book.dat","ab");struct Book book;printf("請輸入圖書名稱:\n");scanf("%s",book.name);printf("請輸入ISBN號:\n");scanf("%s",book.ISBN);printf("請輸入作者:\n");scanf("%s",book.author);printf("請輸入庫存量:\n");scanf("%d",&book.count1);book.count2 = book.count1; //剛添加的書余量等于庫存book.search_Num = 0; //新添加的書檢索量為0N1++;printf("該書已入庫!\n");if(fwrite(&book,len3,1,fp)!=1){printf("file write error!\n");exit(0);}fclose(fp); }void book_Research() //圖書信息查詢函數(shù) {struct Book *head = book_List("rb"); //將文件數(shù)據(jù)取出來重新構建鏈表struct Book *p;p = head;struct Book book;printf("請輸入ISBN號:\n");scanf("%s",book.ISBN);while(p!=NULL){if(strcmp(p->ISBN,book.ISBN)==0){printf("**************************************************************************************************\n");printf("**\t書名\t\tISBN號\t\t作者\t\t庫存\t\t余量\t\t檢索量\t**\n");printf("**%12s%14s%16s%13d%16d%17d\t**\n",p->name,p->ISBN,p->author,p->count1,p->count2,p->search_Num);//不能用book來輸出,因為book里邊只有書名和ISBN號printf("***************************************************************************************************\n");p->search_Num++;break;}p = p->next;}book_Save(head); //因為檢索量信息有改動,需要重新存儲if(p==NULL){printf("圖書信息不存在!\n");} } void book_Delete() //刪除函數(shù) {struct Book *head = book_List("rb");struct Book *p1,*p2;struct Book book;printf("請輸入要刪除的書籍ISBN號:\n");scanf("%s",book.ISBN);p1 = p2 = head;while(strcmp(book.ISBN,p1->ISBN)!=0 && p1->next!=NULL){p2 = p1;p1 = p1->next;}if(strcmp(book.ISBN,p1->ISBN)==0){if(p1==head){head = p1->next;}else {p2->next = p1->next;free(p1);}} else{printf("輸入信息有誤!\n");}printf("書籍刪除成功!\n");N1--;book_Save(head); }void book_Change(struct Administrator *p1) //書籍信息修改 {struct Book *head = book_List("rb");struct Book *p;struct Book book;printf("請輸入ISBN號:\n");scanf("%s",book.ISBN);p = head;while(p!=NULL){if(strcmp(p->ISBN,book.ISBN)==0){int i;printf("請選擇相應的修改項:\n");scanf("%d",&i);switch(i){case 1: {printf("請輸入修改后的ISBN號:\n");scanf("%s",p->ISBN);} break;case 2: {printf("請輸入修改后的作者名:\n");scanf("%s",p->author);} break;case 3: {printf("請輸入修改后的庫存量:\n");scanf("%d",&p->count1);} break;case 4: {printf("請輸入修改后的余量:\n");scanf("%d",&p->count2);} break;case 5: menu5(p1);break;case 6:default: printf("\n退出成功!\n");break;} printf("圖書信息修改成功!\n");break;}p = p->next; //簡化遍歷過程,不要用p2指針,容易亂}if(p==NULL){printf("圖書信息不存在!\n");}book_Save(head); }void reader_Print() //讀者信息一覽表 {struct Reader *head = reader_List("rb");struct Reader *p;p = head;printf("******************************************************************\n");printf("**\t\t 讀 者 信 息 一 覽 表 \t\t\t**\n");printf("******************************************************************\n");printf("**\t用戶名\t\t密碼\t\t\t借閱數(shù)量\t**\n");while(p!=NULL){printf("\n**\t%s\t\t%s\t\t%d\t\t**\n",p->name,p->password,p->count);p = p->next;}printf("******************************************************************\n"); }void administrator_Print() //管理員信息一覽表 {struct Administrator *head = administrator_List("rb");struct Administrator *p;p = head;printf("******************************************************************\n");printf("**\t\t管 理 員 信 息 一 覽 表\t\t\t**\n");printf("******************************************************************\n");printf("\n**\t\t用戶名\t\t\t密碼\t\t\t**\n");while(p!=NULL){printf("\n**\t\t%s\t\t\t%s\t\t**\n",p->name,p->password);p = p->next;}printf("\n******************************************************************\n"); } void book_TopN(int N) //N<=150 但是要把數(shù)據(jù)全部拿出來,但只輸出前N個 {struct Book *p1,*p2,temp;p1 = p2 = (struct Book*)malloc(len3*N);FILE *fp;fp = file_Open("Book.dat","rb");for(int i=0;i<N;i++){if(fread(p1,len3,1,fp)!=1){printf("file read error!\n");return ;}p1++;}for(int i=0;i<N;i++){ //冒泡排序for(int j=i+1;j<N;j++){if(p2[j].search_Num>p2[i].search_Num){temp = p2[i];p2[i] = p2[j];p2[j] = temp;}}}int n;printf("請輸入Top_n:\n");scanf("%d",&n);printf("******************************************************************************************\n");printf("**\t\t\t\t圖 書 熱 搜 排 名 Top%d\t\t\t\t**\n",n);printf("******************************************************************************************\n");printf("**\t\t書 名\t\t\t\t作 者\t\t\t檢 索 量\t**\n");for(int i=0;i<n;i++){printf("**%23s%27s%25d\t\t**\n",p2[i].name,p2[i].author,p2[i].search_Num);}printf("******************************************************************************************\n");free(p2); }void reader_bPrint(struct Reader *p) //讀者借閱信息一覽 {int count = p->count;struct Book *head = book_List("rb");struct Book *p1;printf("\n***************************************************************************************************\n");printf("**\t\t\t\t讀 者 借 閱 信 息 信 息 一 覽 表\t\t\t\t**\n");printf("***************************************************************************************************\n");printf("**\t書名\t\tISBN號\t\t作者\t\t庫存\t\t余量\t\t檢索量\t**\n\n");for(int i=0;i<count;i++){p1 = head; //還需要重新找出這本書,然后輸出信息while(p1!=NULL){if(strcmp(p1->ISBN,p->books[i].ISBN)==0){printf("**%12s%14s%16s%13d%16d%17d\t**\n",p1->name,p1->ISBN,p1->author,p1->count1,p1->count2,p1->search_Num);break;}p1 = p1->next;}}printf("\n***************************************************************************************************\n"); }void reader_Borrow(struct Reader *p) {struct Book *head = book_List("rb");struct Book *p1;struct Book book;printf("請輸入圖書名稱:\n");scanf("%s",book.name);p1 = head;while(p1!=NULL){if(strcmp(p1->name,book.name)==0){if(p->count==10){printf("借書已達上限!\n");break;}else if (p1->count2==0){printf("該書已全部被借出!\n");break;}else { // 先修改書的信息p1->search_Num++;p1->count2--;break;}}p1 = p1->next;}book_Save(head);//再修改讀者中關于所借書籍的信息struct Reader *head1 = reader_List("rb");struct Reader *p2;p2 = head1;while(p2!=NULL){if(strcmp(p2->name,p->name)==0){strcpy(p2->books[p2->count].name,p1->name);strcpy(p2->books[p2->count].ISBN,p1->ISBN);strcpy(p2->books[p2->count].author,p1->author);p2->books[p2->count].count1=p1->count1;p->books[p->count].count2=p1->count2;p->books[p->count].search_Num=p1->search_Num;p2->count++;break;}p2 = p2->next;}reader_Save(head1); //要把修改后的讀者信息存回文件里邊printf("借書成功\n"); }void reader_Return(struct Reader *p) //還書 {struct Book *head = book_List("rb");struct Book *p1;struct Book book;printf("請輸入圖書名稱:\n");scanf("%s",book.name);p1 = head;while(p1!=NULL){if(strcmp(p1->name,book.name)==0){// 先修改書的信息p1->count2++;break;}p1 = p1->next;}book_Save(head);//再修改人的信息struct Reader *head1 = reader_List("rb"); //要把修改后的讀者信息存回文件里邊struct Reader *p2;p2 = head1;while(p2!=NULL){if(strcmp(p2->name,p->name)==0){p2->count--;break;}p2 = p2->next;}reader_Save(head1);printf("還書成功!\n"); }//v1.0結束基本功能的代碼 //v1.1菜單功能完善,各項功能檢查 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<windows.h> #include<conio.h>#define len1 sizeof(struct Reader) #define len2 sizeof(struct Administrator) #define len3 sizeof(struct Book)struct Reader *reader_Create(int N); void reader_Save(struct Reader *head); struct Administrator *administrator_Create(int N); void administrator_Save(struct Administrator *head); struct Book *book_Create(int N); void book_Save(struct Book *head); FILE *file_Open(char fname[],char fopenWay[]); struct Book *book_List(char fopenWay[]); struct Reader *reader_List(char fopenWay[]); struct Administrator *administrator_List(char fopenWay[]);struct Administrator { //管理員char name[20]; //用戶名char password[20]; //登陸密碼struct Administrator *next; //一定要注意administrator的拼寫 };struct Book { //圖書char name[30];char ISBN[20];char author[30];int count1; //庫存總量int count2; //庫存余量int search_Num; //檢索量struct Book *next; };struct Reader { //讀者char name[20]; //用戶名char password[20]; //登陸密碼int count; //已借數(shù)量struct Book books[10]; //借書信息,上限是10本 //如果把Book結構體聲明放在Reader后面,程序會報錯struct Reader *next; };struct Reader *reader_Create(int N) {struct Reader *head;struct Reader *p1,*p2;int n=1;p1 = p2 = (struct Reader*)malloc(len1);scanf("%s%s%d",p1->name,p1->password,&p1->count);for(int i=0;i<p1->count;i++){scanf("%s%s%s%d%d%d",p1->books[i].name,p1->books[i].ISBN,p1->books[i].author,&p1->books[i].count1,&p1->books[i].count2,&p1->books[i].search_Num);}head = NULL;while(n<=N){if(n==1){head = p1;}else {p2->next = p1;}p2 = p1;if(n<N){p1 = (struct Reader *)malloc(len1);scanf("%s%s%d",p1->name,p1->password,&p1->count);for(int i=0;i<p1->count;i++){scanf("%s%s%s%d%d%d",p1->books[i].name,p1->books[i].ISBN,p1->books[i].author,&p1->books[i].count1,&p1->books[i].count2,&p1->books[i].search_Num);}}n++;}p2->next = NULL;printf("數(shù)據(jù)錄入成功!\n");return head; }void reader_Save(struct Reader *head) {FILE *fp;fp = file_Open("Reader.dat","wb");struct Reader *p = head;while(p!=NULL){if(fwrite(p,len1,1,fp)!=1){printf("file write error!\n");return ;}p = p->next;}fclose(fp);printf("恭喜你!讀者數(shù)據(jù)保存成功!\n"); }struct Administrator *administrator_Create(int N) {struct Administrator *head;struct Administrator *p1,*p2;int n=1;head = NULL;p1 = p2 = (struct Administrator *)malloc(len2);scanf("%s%s",p1->name,p1->password);while(n<=N){if(n==1){head = p1;}else {p2->next = p1;}p2 = p1;if(n<N){p1 = (struct Administrator *)malloc(len2);scanf("%s%s",p1->name,p1->password);}n++; //注意這個n的位置,不能放在上面的if里邊,會引起死循環(huán)}p2->next = NULL;printf("數(shù)據(jù)錄入成功!\n");return head; }void administrator_Save(struct Administrator *head) {FILE *fp;fp = file_Open("Administrator.dat","wb");struct Administrator *p = head;while(p!=NULL){if(fwrite(p,len2,1,fp)!=1){printf("file write error!\n");return ;}p = p->next;}fclose(fp);printf("恭喜你!管理員信息保存成功!\n"); }struct Book *book_Create(int N) {struct Book *head;struct Book *p1,*p2;head = NULL;p1 = (struct Book*)malloc(len3);scanf("%s%s%s%d%d%d",p1->name,p1->ISBN,p1->author,&p1->count1,&p1->count2,&p1->search_Num);int n=1;while(n<=N){if(n==1){head = p1;}else {p2->next = p1;}p2 = p1;if(n<N){p1 = (struct Book*)malloc(len3);scanf("%s%s%s%d%d%d",p1->name,p1->ISBN,p1->author,&p1->count1,&p1->count2,&p1->search_Num);}n++;}p2->next = NULL;printf("數(shù)據(jù)錄入成功!\n");return head; }void book_Save(struct Book *head) {FILE *fp;fp = file_Open("Book.dat","wb");struct Book *p;p = head;while(p!=NULL){if(fwrite(p,len3,1,fp)!=1){printf("file write error!\n");return ;}p = p->next;}fclose(fp);printf("恭喜你!書籍信息保存成功!\n"); } //漢字無法在cmd終端顯示,但在dev彈出終端中可以顯示FILE *file_Open(char fname[],char fopenWay[])//文件打開函數(shù),相當有用 {FILE *fp;if((fp=fopen(fname,fopenWay))==NULL){printf("cannot open file!\n");return ;}return fp; }struct Book *book_List(char fopenWay[]) {struct Book *head=NULL;struct Book *p1,*p2;FILE *fp;fp = file_Open("Book.dat",fopenWay);p1 = p2 = (struct Book*)malloc(len3);int n=1;fread(p1,len3,1,fp);while(!feof(fp)){ //這里有一個關于文件位置標記的bugif(n==1){head = p1;}else {p2->next = p1;}p2 = p1;p1 = (struct Book*)malloc(len3);fread(p1,len3,1,fp);n++;}fclose(fp);p2->next = NULL;free(p1);return head; }struct Reader *reader_List(char fopenWay[]) {struct Reader *head=NULL;struct Reader *p1,*p2;FILE *fp;fp = file_Open("Reader.dat",fopenWay);p1 = p2 = (struct Reader*)malloc(len1);int n=1;fread(p1,len1,1,fp);while(!feof(fp)){if(n==1){head = p1;}else {p2->next = p1;}p2 = p1;p1 = (struct Reader*)malloc(len1);fread(p1,len1,1,fp);n++;}fclose(fp);p2->next = NULL;free(p1);return head; }struct Administrator *administrator_List(char fopenWay[]) {struct Administrator *head=NULL;struct Administrator *p1,*p2;FILE *fp;fp = file_Open("Administrator.dat",fopenWay);p1 = p2 = (struct Administrator*)malloc(len2);int n=1;fread(p1,len2,1,fp);while(!feof(fp)){if(n==1){head = p1;}else {p2->next = p1;}p2 = p1;p1 = (struct Administrator*)malloc(len2);fread(p1,len2,1,fp);n++;}fclose(fp);p2->next = NULL;free(p1);return head; }總結
以上是生活随笔為你收集整理的C语言课设——图书信息管理系统的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022年对话技术梳理:科研进展、产品创
- 下一篇: flask框架初学-10-restful