#關于用C語言(c++類似)撰寫一個在控制臺展示的圖書管理系統(幫朋友寫的課程作業)
#其中只有圖書增加 洗掉 借書 還書 查找圖書 5個功能(小試牛刀)
#工具:visual studio2019
#設計圖

#思路是:打算用鏈表操作資料 然后把資料寫入到txt檔案 每次執行資料操作前從txt檔案把資料讀取到鏈表
下面先看看功能展示圖






#下面貼代碼,因為只是小作業,所以沒有用良好的撰寫習慣,只用了一個.c檔案就把所有代碼寫完了(無自定義頭檔案)
1.include要用的頭檔案,定義struck結構體,定義函式
#define _CRT_SECURE_NO_WARNINGS//只會在該檔案里起作用,下面會用到一些不安全函式(版本問題)strcpy,scanf
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#pragma warning(disable:4996)
struct book {
int bid; //書本號
char bname[100]; //書名
char wname[100]; //作者
char publish[100]; //出版社
int present_count; //當前在架冊數
int old_count; //館藏冊數
char show[100]; //書本簡介
struct book* next; //結構體內指標變數
};
//定義函式
struct book* creatbook(); //創建鏈表
struct book* addbook(struct book* head); //添加圖書
int yanzheng(struct book* head, int m); //驗證新添加的圖書編碼是否已存在
void deletebook(struct book* head); //洗掉圖書
void fprint(struct book* head); //將鏈表寫入檔案
struct book* load(); //從檔案中讀取資訊并建成鏈表
void num_chaxun(struct book* head); //按圖書編號查詢圖書
void xiugai(struct book* head); //借閱書本
void xiugai2(struct book* head); //歸還書本
2.撰寫程式入口main函式
int main()
{
int choice, x;
struct book* head = NULL;//初始化頭指標
x = 1;
while (x) {
system("cls");
printf("*******************************************************\n");
printf("* 圖 書 館 管 理 系 統 *\n");
printf("* 主選單 *\n");
printf("* *\n");
printf("* 1,圖書上架 *\n");
printf("* 2,圖書下架 *\n");
printf("* 3,查找圖書 *\n");
printf("* 4,圖書出借 *\n");
printf("* 5,圖書歸還 *\n");
printf("* 6,退出系統 *\n");
printf("* *\n");
printf("* 請選擇選單項:(1^6) *\n");
printf("*******************************************************\n");
printf("請輸入所選擇的序號:");
scanf("%d", &choice);
getchar();//獲得鍵盤輸入
system("cls");
switch (choice)
{
case 6:
x = 0; break;
case 1:
head = load();//從檔案中讀取資料到鏈表
if (head == NULL) {
head = creatbook();錄入實體到txt檔案,其實這個方法很蠢 寫的時候沒想到,可以直接在txt手動加實體就好了
head = addbook(head);
fprint(head);
printf("上架成功!\n");
getchar();
break;
}
else {
head = addbook(head);
fprint(head);
printf("上架成功!\n");
getchar();
break;
}
case 2:
head = load();
if (head == NULL) {
printf("書庫為空,請先上架書本!\n");
getchar();
break;
}
else {
deletebook(head);
getchar();
break;
}
break;
case 3:
head = load();
if (head == NULL) {
printf("書庫為空,請先上架書本!\n");
getchar();
break;
}
else {
num_chaxun(head);
getchar();
break;
}
break;
case 4:
head = load();
if (head == NULL) {
printf("書庫為空,請先上架書本!\n");
getchar();
break;
}
else {
xiugai(head);
getchar();
break;
}
break;
case 5:
head = load();
if (head == NULL) {
printf("書庫為空,請先上架書本!\n");
getchar();
break;
}
else {
xiugai2(head);
getchar();
break;
}
break;
}
}
}
3.函式撰寫
//錄入資料并形成鏈表
struct book* creatbook()
{
struct book* head, * tail, * p;
//初始時給txt檔案添加一個實體先 免得報空指標錯誤,排錯時間更多 不如提前堵住可能報錯的問題
int num=1, num2=1, num3=1;
char bname[100]="實體", wname[100]= "實體", press[100]= "實體", sort[100]= "實體";
//sizeof運算子以位元組形式給出了其運算元的存盤大小
int size = sizeof(struct book);
head = tail = NULL;
//malloc函式回傳一個指標 ,指向已分配大小的記憶體,如果請求失敗,則回傳 NULL,
p = (struct book*)malloc(size);
p->bid = num;
//strcpy函式對字串進行復制拷貝之類的操作
strcpy(p->bname, bname);
strcpy(p->wname, wname);
strcpy(p->publish, press);
strcpy(p->show, sort);
p->present_count = num2;
p->old_count = num3;
p->next = NULL;
if (head == NULL)
head = p;
else
tail->next = p;
tail = p;
fprint(head);//呼叫寫入資料到txt檔案函式
return head;
}
//將鏈表寫入檔案
void fprint(struct book* head)
{
FILE* fp;//檔案指標
char ch = '1';
struct book* p1;
if ((fp = fopen("f1.txt", "w")) == NULL) {//打開檔案
printf("File open error!\n");
exit(0);
}
fputc(ch, fp);//回傳值:在正常呼叫情況下,函式回傳寫入檔案的字符的ASCII碼值,出錯時,回傳EOF(-1),當正確寫入一個字符或一個位元組的資料后,檔案內部寫指標會自動后移一個位元組的位置,EOF是在頭檔案 stdio.h中定義的宏,
for (p1 = head; p1; p1 = p1->next) {
fprintf(fp, "%d %s %s %s %d %d %s\n", p1->bid, p1->bname, p1->wname, p1->publish, p1->present_count, p1->old_count, p1->show);
}
fclose(fp);
}
從txt檔案中讀取資料并建成鏈表
struct book* load()
{
FILE* fp;
char ch;
struct book* head, * tail, * p1;
head = tail = NULL;
if ((fp = fopen("f1.txt", "r")) == NULL) {
printf("File open error!\n");
exit(0);
}
//從檔案指標指定的檔案中讀入一個字符,該字符的ASCII值作為函式的回傳值,若回傳值為EOF,說明檔案結束,EOF是檔案結束標志,值為-1,
ch = fgetc(fp);
if (ch == '1') {
while (!feof(fp)) {
p1 = (struct book*)malloc(sizeof(struct book));
fscanf(fp, "%d%s%s%s%d%d%s\n", &p1->bid, p1->bname, p1->wname, p1->publish, &p1->present_count, &p1->old_count, p1->show);
if (head == NULL)
head = p1;
else
tail->next = p1;
tail = p1;
}
tail->next = NULL;
fclose(fp);
return head;//回傳值可用來確定檔案中是否有資料(圖書館中是否有書)
}
else
return NULL;
}
//插入結點,并且插入后仍按一定順序存盤
struct book* addbook(struct book* head)
{
struct book* ptr, * p1, * p2, * p;
p1 = NULL;
char bname[100], wname[100], press[100], sort[100];
int size = sizeof(struct book);
int bid, present_count, old_count ,n ;
do {
printf("請輸入圖書編號:");
scanf("%d", &bid);
n = yanzheng(head, bid);//呼叫函式判斷該編號是否存在
if (n == 0)
break;
else
printf("您輸入的編號已存在,請重新輸入!\n");
} while (1);
printf("請輸入圖書名:");
scanf("%s", bname);
getchar();
printf("請輸入作者名:");
scanf("%s", wname);
getchar();
printf("請輸入出版社:");
scanf("%s", press);
getchar();
printf("請輸入當前在架冊數:");
scanf("%d", &present_count);
getchar();
printf("請輸入管藏冊數:");
scanf("%d", &old_count);
getchar();
printf("請輸入書本簡介:");
scanf("%s", sort);
getchar();
p = (struct book*)malloc(size);
p->bid = bid;
strcpy(p->bname, bname);
strcpy(p->wname, wname);
strcpy(p->publish, press);
strcpy(p->show, sort);
p->present_count = present_count;
p->old_count = old_count;
p2 = head;
ptr = p;
while ((ptr->bid > p2->bid) && (p2->next != NULL)) {
p1 = p2;
p2 = p2->next;
}//1,2,3,4,插入5 要把p2頭指到4 此時p1指到3 ;1,2,5 插入4 要把p2指到5 此時p1指到2
if (ptr->bid <= p2->bid) {
if (head == p2)
head = ptr;
else {
p1->next = ptr;
p->next = p2;
}
}
else {
p2->next = ptr;
p->next = NULL;
}
return head;
}
//驗證添加的圖書編號是否已存在
int yanzheng(struct book* head, int m)
{
struct book* p;
p = head;
while (p != NULL) {
if (p->bid == m)
break;
p = p->next;
}
if (p == NULL)
return 0;
else
return 1;
}
//洗掉圖書資訊
void deletebook(struct book* head)
{
int a;
char b, ch = '1';
struct book* p1, * p2;
FILE* fp;
printf("請輸入要洗掉的圖書編號:");
scanf("%d", &a);
p1 = head;
p2 = NULL;
if (p1->bid == a && p1->next == NULL) { //假如txt里只有最初添加的實體一組資料時
printf("是否下架唯一的書!(y/n)\n");
getchar();
scanf("%c", &b);
getchar();
switch (b) {
case 'n':
break;
case 'y':
if ((fp = fopen("f1.txt", "w")) == NULL) {
printf("File open error!\n");
exit(0);
}
fclose(fp);
printf("檔案已清空!\n");
}
}
else {
while (p1->bid != a && p1->next != NULL) {//不止一組資料,要洗掉節點也不是頭節點時,尋找到對應編號對應的資料
p2 = p1;
p1 = p1->next;
}
if (p1->next == NULL) {
if (p1->bid == a) {
p2->next = NULL;
printf("是否確定從書架中徹底洗掉該圖書?(y/n)\n");
getchar();
scanf("%c", &b);
switch (b) {
case 'n':
break;
case 'y':
fprint(head);
printf("洗掉成功!\n");
getchar();
break;
}
}
else {
printf("沒有找到要洗掉的資料!\n");
getchar();
}
}
else if (p1 == head) {//洗掉節點時頭結點時
head = p1->next;
printf("是否確定從書架中徹底洗掉該圖書?(y/n)\n");
getchar();
scanf("%c", &b);
switch (b) {
case 'n':
break;
case 'y':
fprint(head);
printf("洗掉成功!\n");
getchar();
break;
}
}
else {
p2->next = p1->next;
printf("是否確定從書架中徹底洗掉該圖書?(y/n)\n");
getchar();
scanf("%c", &b);
switch (b) {
case 'n':
break;
case 'y':
fprint(head);
printf("洗掉成功!\n");
getchar();
break;
}
}
}
}
//按編號查詢圖書資訊
void num_chaxun(struct book* head)
{
int a;
struct book* p;
printf("請選擇您要查詢的圖書編號:");
scanf("%d", &a);
getchar();
p = head;
while (p != NULL) {
if (p->bid == a)
break;
p = p->next;
}
if (p == NULL) {
printf("沒有找到該編號的圖書!\n");
}
else {
printf("書本資訊:\n");
printf("書名:%s\n", p->bname);
printf("作者:%s\n", p->wname);
printf("當前在架冊數:%d\n", p->present_count);
printf("館藏冊數:%d\n", p->old_count);
printf("本書簡介:%s\n", p->show);
}
}
//借閱書本 更改txt內對應書本編號的數量
void xiugai(struct book* head)
{
int a;
struct book* p;
printf("請輸入要借的書本號:");
scanf("%d", &a);
p = head;
while (p != NULL) {
if (p->bid == a)
break;
p = p->next;
}
if (p == NULL) {
printf("沒有找到該編號的圖書!\n");
getchar();
}
else {
printf("書名:%s\n", p->bname);
printf("作者:%s\n", p->wname);
printf("當前在架冊數:%d\n", p->present_count);
printf("館藏冊數:%d\n", p->old_count);
printf("本書簡介:%s\n", p->show);
getchar();
p->old_count = p->old_count - 1;
p->present_count = p->present_count - 1;
fprint(head);//修改后寫入檔案
printf("借閱成功\n");
getchar();
}
}
//歸還書籍,改變數量
void xiugai2(struct book* head){
int a;
struct book* p;
printf("請輸入要還的書本號:");
scanf("%d", &a);
p = head;
while (p != NULL) {
if (p->bid == a)
break;
p = p->next;
}
if (p == NULL) {
printf("沒有找到該編號的圖書!\n");
getchar();
}
else {
printf("書名:%s\n", p->bname);
printf("作者:%s\n", p->wname);
printf("當前在架冊數:%d\n", p->present_count);
printf("館藏冊數:%d\n", p->old_count);
printf("本書簡介:%s\n", p->show);
getchar();
p->old_count = p->old_count + 1;
p->present_count = p->present_count + 1;
fprint(head);
printf("歸還成功\n");
getchar();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/274522.html
標籤:其他
上一篇:自己做的c++小程式,加入我!
