相关视频——C语言课程设计实战:图书管理系统!计算机专业同学的一大难题,今天用代码实战演示,手把手带你完成!_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili


1.前言

在开始之前我们要解决三个问题。

  1. 指针如何变成变量

    1. 用变量的地址

      1
      2
      3
      4
      int* p = NULL;
      int a = 1;
      p = &a;
      *p = 1001;
    2. 动态内存申请

      1
      2
       p = (int*)malloc(sizeiof(int));
      *p = 10033;
  2. 什么是结构体?

    就是一种类型,将几段内存组合成一段内存。

    1
    2
    3
    4
    5
    6
    struct data
    {
    int A;
    float B;
    char name[10];
    };

    如何访问?

    1. 变量——.成员,

      1
      2
      struct data C;
      C.A = 1001;
    2. 指针——->,指针指向运算符,C->A

      1
      2
      struct data *sb = &C;
      sb->A = 1002;
  3. 什么是链表?

多个结构体变量链接在一起的线性结构。就是一个变量。

2.代码实现

缺陷:

不包括用户信息

借出和归还没有放到文件操作里面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
//图书管理系统 
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//3.数据的设计
// 3.1程序用什么东西处理数据 -数组 -链表 ——无非就是去考虑用什么容器来装数据
// 3.2数据的结构 --- 图书的信息
struct bookInfo
{
char name[20];//书名
float price;//价格
int num;//数量
};
struct Node
{
//链表的第一个结点不存放数据,叫做有表头链表。
struct bookInfo data;
struct Node* next;
};
struct Node* list = NULL;
//创建表头 表头就是一个结构体变量
struct Node* creatHead()
{
//动态内存申请
struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
//变量的基本规则——使用前必须初始化
headNode->next = NULL;
return headNode;
};
//创建结点——为插入做准备
//把用户的数据编程结构体变量
struct Node* creatNode(struct bookInfo data)
{
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
};
//插入-只需要一种插入方法-表头法插入
void insertNodeByHead(struct Node* headNode,struct bookInfo data)
{
struct Node* newNode = creatNode(data);
//必须先链接后断开
newNode->next = headNode->next;
headNode->next = newNode;
}
//尾插法
//void insertNodeByTail(struct Node* headNode, int data)
//{
// struct Node* pMove = headNode;
// while (pMove->next != NULL)
// {
// pMove = pMove->next;
// }
// struct Node* newNode = creatNode(data);
// pMove->next = newNode;
//}
//指定位置删除
void deleteNodeByName(struct Node* headNode, char* bookName)
{
struct Node* posLeftNode = headNode;
struct Node* posNode = headNode->next;
//书籍名字是字符串,所以要采用字符串比较函数来处理。
while (posNode != NULL && strcmp(posNode->data.name,bookName))
{
posLeftNode = posNode;
posNode = posLeftNode->next;
posNode = posLeftNode->next;
}
//讨论查找的结果
if (posNode == NULL)
return ;
else
{
printf("delete successful\n");
posLeftNode->next = posNode->next;
free(posNode);
}
}
struct Node* searchByName(struct Node* headNode, char* bookName)
{
struct Node* posNode = headNode->next;
while (posNode != NULL && strcmp(posNode->data.name,bookName))
{
posNode = posNode->next;
}
return posNode;
}
//打印链表
void printList(struct Node* headNode)
{
//定义一个指针,从第二个开始打印
struct Node* pMove = headNode->next;
printf("书名\t价格\t数量\n");
while (pMove != NULL)
{
//打印数据——剥洋葱
printf("%s\t%.1f\t%d\n", pMove->data.name,pMove->data.price,pMove->data.num);
pMove = pMove->next;
}
}


//1.写界面---菜单---模块
void mainMenu()
{
printf("——————————————\n");
printf("-Libraty manangement system-\n");
printf("————0.exit———————-\n");//退出
printf("————1.resiger——————\n");//登记
printf("————2.browse————-----\n");//浏览
printf("————3.borrow————-----\n");//借
printf("————4.back————-------\n");//还
printf("————5.sort————-------\n");//排序
printf("————6.delete————-----\n");//删除
printf("————7.seek————-------\n");//查找
printf("——————————————\n");
printf("——please input 0 to 7------\n");//提示

}
//直接文件操作
//所有的文件都在这个容器里面,做文件操作就是对这个List进行文件操作
//运行的时候把文件的信息读到List里面
//结束的时候把List里面的信息同步到文件里面
//文件存(写)操作
void saveInfoToFile(const char* fileName, struct Node* headNode)
{
FILE* fp = fopen(fileName, "w");
struct Node* pMove = headNode->next;
while (pMove != NULL)
{
fprintf(fp,"%s\t%.1f\t%d\n",pMove->data.name,pMove->data.price,pMove->data.num);
pMove = pMove->next;
}
fclose(fp);
}
//文件读操作
void readInfoFromFile(const char* fileName, struct Node* headNode)
{
FILE* fp = fopen(fileName, "r");//第一次打开文件肯定是不存在的
if (fp == NULL)
{
//不存在就把文件创建出来
//如果第一次打开文件是空的,用w+方式打开文件,可读可写。
fp = fopen(fileName, "w+");
}
struct bookInfo tempData;
while (fscanf(fp, "%s\t%f\t%d\n", tempData.name, &tempData.price, &tempData.num) != EOF);
{
insertNodeByHead(list, tempData);
}
fclose(fp);
}
//算法是一种思想
//冒泡排序
void bubbleSortList(struct Node* headNode)
{
for (struct Node* p = headNode->next; p != NULL; p = p->next)
{
for (struct Node* q = headNode->next; q->next != NULL; q = q->next)
{
if (q->data.price > q->next->data.price)
{
//交换值
struct bookInfo tempData = q->data;
q->data = q->next->data;
q->next->data = tempData;
}
}
}
printList(headNode);
}
//2.交互-按键处理-跳转
void keyDown()
{
int userKey = 0;
struct bookInfo tempbook;//产生一个临时的变量存储书籍信息
struct Node* result = NULL;
scanf("%d",&userKey);
switch(userKey)
{
case 0:
printf("【exit】\n");
printf("successful\n");
system("pause");
exit(0);//关闭整个程序
break;
case 1:
printf("【resiger】\n");
printf("input your book's information(name,price,num):");
scanf("%s%f%d",tempbook.name, &tempbook.price, &tempbook.num);
//第一个temobook.name是字符串 不用取地址
insertNodeByHead(list, tempbook);
saveInfoToFile("bookinfo.txt",list);
break;
case 2:
printf("【browse】\n");
printList(list);
break;
case 3:
printf("【borrow】\n");
//书籍存在可以借阅,存在书的数量-1,不存在借阅失败
printf("please input book name\n");
scanf("%s", tempbook.name);
result = searchByName(list,tempbook.name);
{
if (result == NULL)
{
printf("without the book\n");
}
else
{
if (result->data.num >= 1)
{
result->data.num--;
printf("borrow successful\n");
}
else
{
printf("the book it's not here\n");
}
}
}
break;
case 4:
printf("【back】\n");
//把当前书籍的数量+1
printf("please input book name\n");
scanf("%s", tempbook.name);
result = searchByName(list, tempbook.name);
{
if (result == NULL)
{
printf("illegal book\n");
}
else
{
result->data.num++;
}
}
break;
case 5:
printf("【sort】\n");
bubbleSortList(list);
break;
case 6:
printf("【delete】\n");
printf("please input book name\n");
scanf("%s", tempbook.name);
deleteNodeByName(list, tempbook.name);
saveInfoToFile("bookinfo.txt", list);
break;
case 7:
printf("【seek】\n");
printf("please input book name\n");
scanf("%s",tempbook.name);
result = searchByName(list, tempbook.name);
if (result == NULL)
{
printf("can't find\n");
}
else
{
printf("name\tprice\tnum\n");
printf("%s\t%.1f\t%d\n", result->data.name, result->data.price, result->data.num);
}
break;
default:
printf("【error】\n");
break;
}
}
int main(void)
{
list = creatHead();
readInfoFromFile("bookinfo.txt",list);
while (1)
{
mainMenu();
keyDown();
system("pause");//防闪退
system("cls");//清除
}
system("pause");
return 0;
}