【C语言项目实战7——文件】

文件

文件的打开:

ANSI C规定了标准/输出函数库,用fopen函数来实现打开文件。fopen函数的原型定义在头文件stdio.h中。
一般形式:
FILE *fp; fp=fopen(filename,mode);
fopen函数有两个参数:
filename:一个指向字符的指针
mode:系统规定的字符串,表示文件的操作属性
mode字符串对应的操作模式:

读写方式 文件类型 含义 读写方式 文件类型 含义
“r” 文本文件 打开文本,只读 “rb+” 二进制文件 打开二进制文件,读、覆盖写
“w” 文本文件 建立文本文件,只写 “wb+” 二进制文件 打开二进制文件,先写后读
“a” 文本文件 打开文本文件,追加 “ab+” 二进制文件 打开二进制文件,读,追加
“rb” 二进制文件 打开二进制文件,只读 “rt” 文本文件 打开文本文件,只读
“wb” 二进制文件 建立二进制文件,只写 “wt” 文本文件 建立文本文件,只写
“ab” 二进制文件 打开二进制文件,读、追加 “at” 文本文件 打开文本文件,追加
“r+” 文本文件 打开文本文件,读、覆盖写 “rt+” 文本文件 打开文本文件,读、覆盖写
“w+” 文本文件 打开文本文件,先写后读 “wt+” 文本文件 打开文本文件,先写后读
“a+” 文本文件 打开文本文件,读、追加 “at+” 文本文件 打开文本文件,读、追加
三个基本模式:
“r”(read)模式总是打开一个已经存在的文件,如果文件不存在则出错。
“w”(write)模式建立一个新文件,如果文件已经存在,那么先删除存在的文件,再建立新文件。
“a”(append)打开一个存在的文件,在文件的尾部追加数据。


  • 三个追加符:
    “b”(binary)表示二进制文件。
    “t”(或默认)表示文本文件。
    “+”表示将模式扩展为可读、可写方式。

文件的一般打开方式

fopen()函数打开文件有可能失败。如用“r”模式打开不存在的文件,此时会返回一个空指针NULL。则程序无法继续输入/输出数据。故需要在打开文件时判断是否有错。

FILE *fp;
if((fp=fopen(filename,mode))==NULL)
{
    printf("打开文件错误!\n");
    exit(1);/*由exit函数终止程序运行。*/
}

  • 打开文件将通知编译系统3个信息:
    1.使用的文件指针
    2.需要打开的文件名
    3.使用文件的方式

文件的关闭

文件打开的目的是为了读/写,当文件使用完毕后,应当关闭文件。关闭文件的三个目的:
1.保证文件的数据不丢失,将缓冲区中的数据回写文件。
2.释放缓冲区。
3.切断文件指针与文件的关联,使关闭后的文件指针可以用于打开其他文件。
C语言定义了关闭文件的标准函数fclose。函数原型定义在头文件stdio.h中,其一般形式为:fclose(文件指针);
例如:fclose(fp);//fp是文件指针。

文件的读/写

一.字符输入/输出函数

1.字符输出函数fputc()
用法:fputc(ch,fp);
ch:输出的字符;fp:文件指针变量
功能:写一个字符到fp对应文件的当前位置上。如果调用函数成功,则返回ch的值;如果失败,则返回值EOF(系统定义的宏,值为-1);

2.字符输入函数fgetc()
用法:ch=fgetc(fp);
fp:文件指针变量
功能:从fp对应的当前位置读一个字符。如果调用成功,则返回读到的字符(赋值给ch);如果读到文件结束,则返回EOF(-1)。

3.文件结束检测函数feof()
用法:feof(fp);
fp:文件指针变量
功能:判断文件是否处于文件结束位置。如果文件结束,则返回1,否则返回0。

二.字符串输入/输出函数

1.字符串输入函数fgets()
用法:fgets(str,n,fp);
str:字符指针或数组名;n:整型量,说明输入字符串的最大长度(包括‘\0’);fp:文件指针
功能:从fp对应文件的当前位置,最多输入n-1个字符,在最后加‘\0’,之后放在str为首地址的内存中。
注意:在输入过程中,如果遇到换行符或EOF,输入即结束。函数正常调用,返回str的首地址,当出错或遇到文件结束标志时,返回NULL。

2.字符串输出函数fputs()
用法:fputs(str,fp);
str:函数参数str是字符指针或数组名;fp:文件指针
功能:将首地址是str的字符串输出到fp对应文件的当前位置,自动丢弃str后的‘\0’。函数调用成功后返回值是0,否则是EOF。
在文件使用中,可采用标准的设备文件,系统为每一个设备指定了标准的文件指针名称。
常见的标准设备文件:

文件号 文件指针 标准文件
0 stdin 标准输入设备(键盘)
1 stdout 标准输出设备(显示器)
2 stderr 标准错误设备(显示器)
3 stdaux 标准辅助设备(辅助设备端口)
4 stdprn 标准打印(打印机)

三.文件的格式化输入/输出函数

1.格式化输入函数fscanf()
用法:fscanf(fp,format,&arg1,&arg2,…,&argn);
fp:文件指针;format:格式说明字符串;&arg1…&argn:输入变量的地址列表。
功能:从fp指向的文件的当前位置,顺序读取ASCII码值,按照fomat规定的格式转化为各个变量对应的值,送入指定变量。

2.格式化输出函数fprintf()
用法:fprintf(fp,format,arg1,arg2,…,argn);
fp:文件指针;format:格式说明字符串;arg1…argn:输出参数个数表
功能:按指定的格式(format)将输出列表arg1…argn的值转换成对应的ASCII码表示形式,写入fp文件的当前位置。例如:
fprintf(fp,“%d,%x,%u”,123,145,12);

四.文件的数据块输入/输出函数

1.数据块输入函数fread()
用法:表示从文件中读入数据到内存缓冲区。形式为:fread(buf,size,count,fp);
buf:类型为void指针,表示内存中存放着数据到首地址,通常是数组名或数组指针。
size:无符号整型,表示一次读取的字节数。
count:无符号整型,表示读取的大小为size的块的次数。
fp:文件指针。
功能:从fp指向的文件的当前位置读区size个字节,共count次,读取的总字节数为size*count,存放到首地址为buf的内存中。读取成功则返回读取的项数count。

2.数据块输出函数fwrite()
用法:表示从内存输出数据块到文件中。其一般形式为:
fwrite(buf,size,count,fp);
buf:类型为void指针,表示内存中存放着数据到首地址,通常是数组名或数组指针。
size:无符号整型,表示一次写入的字节数。
count:无符号整型,表示写入的大小为size的块的次数。
fp:文件指针。
功能:从fp指向的地址开始,分count次,每次size个字节,向fp指向的文件的当前位置写数据,共写入count*size个字节。写入成功则返回读取的项数count。

fread()和fwrite()读/写的最小单位是字节,而fscanf()和fprintf()的读/写数据基本单位是以类型为单位的数据对象。so,fread()和fwrite()更适合处理二进制文件,而fscanf()和fprintf()则更适合处理的都是文本文件。

在读取二进制文件时不能用EOF作为文件标志,要用feof函数判断文件是否结束。因为-1可能是一个有效数据。

五.整数输入/输出函数
  • getw 函数(只适用于二进制文件)
    getw函数表示整数输入。一般形式为:
int a;
a=getw(fp);

功能:从fp指向的文件中读取一个整数(2字节),整数由函数返回。只使用于二进制文件。

  • putw 函数(适用于二进制文件)
    putw函数表示整数输出。其一般形式为:
putw(i,fp);

功能:将整数i输出到文件fp之中。

图书管理系统

项目功能需求

题目描述:对图书的库存信息、借阅信息和用户信息进行管理
要求:所有的基础数据均能以文件的形式存储,这些数据包括:
图书信息:图书编号、ISBN、书名、作译者、出版社、价格、复本数、库存量
用户信息:借书证号、姓名、性别、出生日期、专业
借阅信息:图书编号、借书证号、ISBN、结束时间
运行效果:
在这里插入图片描述

【1】

在这里插入图片描述
在这里插入图片描述

【2】

在这里插入图片描述

【3】

在这里插入图片描述
在这里插入图片描述

【信息保存】

在这里插入图片描述

图1 图书管理系统运行效果

知识点分析

利用链表和结构体实现
对各个功能模块进行归类整理;
掌握结构体成员的访问;
使用结构体处理复杂的数据结构;
级联菜单功能的实现。

算法思想

1.根据需求对不同功能实现进行模块分类
2.实现程序反复运行,直至用户菜单选择退出->通过无限循环反复调用start()函数使得程序运行
3.结构体的定义和辅助结构体的设计使用

系统流程图

在这里插入图片描述

图2 图书管理系统流程图

项目实现


1.#include"stdlib.h"
2.#include"string.h"
3.#include"conio.h"
4.#include"malloc.h"
5.#include"stdio.h"
6.#include"time.h"
7.#define bookpath "project 7/tuozhan/Book management system/book.dat" //图书地址
8.#define userpath "project 7/tuozhan/Book management system/user.dat"//用户地址
9.#define borrowpath "project 7/tuozhan/Book management system/borrow.dat"//借阅地址
10.#define idlen 12 //id
11.#define namelen 10 //名字
12.#define sexlen 4 //性别
 
13.typedef struct
14.{
 
15.int borrowid; //借书证号
16.char name[namelen + 1]; //姓名
17.char sex[sexlen + 1]; //性别
18.int born; //出生日期
19.char major[namelen + 1];//专业
 
20.}User;
 
 
 
21.typedef struct node1
22.{
23.User userinf;
24.struct node1* next;//单链表指针
25.}user;
 
 
 
26.typedef struct
27.{
 
28.char bookid[idlen + 1]; //图书编号
29.char name[namelen + 1];//图书名字
30.int ISBN;
31.char writer[namelen + 1];//作译者
32.int price;//价格
33.char press[namelen + 1];//出版社
34.int bor;//复本数
35.int now;//库存量
 
36.}Book;
 
 
37.typedef struct node2
38.{
39.Book bookinf;
40.struct node2* next;
41.}book;
 
42.typedef struct
43.{
 
44.char bookid[idlen + 1];//图书编号
45.char borrowid[idlen + 1];//借书证号
46.int ISBN;
47.char time[idlen + 1];//借书时间
48.}Bor;
 
 
49.typedef struct node3
50.{
51.Bor borrowinf;
52.struct node3* next;
53.}borrow;
 
 
54.static int bookmenu();//图书菜单
55.static int usermenu();//用户菜单
56.static int displaymenu();//主菜单
 
57.static void bookcreate(const char* path);图书信息的建立
 
58.static book* bookimport(FILE* fp);//读取文件的中的图书信息并且返回图书的头指针
 
59.static book* bookinput();//初始化图书信息
 
60.static void displaybook(book* head);//将所有的图书信息输出
 
61.static book* findbookId(book* head, char* id);//查询图书
 
62.static int displaybookrenew();//修改图书信息菜单
 
63.static void renewbook(book* head);//修改图书信息
 
64.static void deletebook(book* head);//删除书籍
 
65.static void addbook(book* head);//增加图书信息
 
66.static void savebook(book* head);//保存图书信息
 
67.static void booksysteam(book* bookhead);//图书信息系统
 
68.static void usercreate(char* path);//用户信息的建立
 
69.static user* userimport(FILE* fp);//读取文件的中的用户信息并且用户的头指针
 
70.static user* userinput();//初始化用户信息
 
71.static void displayuser(user* head);//用户信息输出
 
72.static user* finduserName(user* head, char* name);//查询用户名
 
73.static int displayuserrenew();//修改用户信息菜单
 
74.static void renewuser(user* head);//修改用户信息
 
75.static void deleteuser(user* head);//删除用户信息
 
76.static void adduser(user* head);//增加用户信息
 
77.static void saveuser(user* head);//保存用户信息
 
78.static void usersysteam(user* bookhead);//用户信息系统
 
79.static int borrowmenu();//借阅菜单
 
80.static void borrowcreate(const char* path);//借阅信息的建立
 
81.static borrow* borrowimport(FILE* fp);//读取文件的中的借阅信息并且借阅的头指针
 
82.static borrow* borrowinput();//初始化借阅者信息
 
83.static void displayborrow(borrow* head);//借阅信息输出
 
84.static borrow* findborrowId(borrow* head, char* id);//查询借阅信息
 
85.static int displayborrowrenew();//借阅信息输出
 
86.static void renewborrow(borrow* head);//修改借阅信息
 
87.static void deleteborrow(borrow* head);//删除图书信息
 
88.static void addborrow(borrow* head);//增加借阅信息
 
89.static void saveborrow(borrow* head);//保存借阅信息
 
90.static void borrowsysteam(borrow* borrowhead);//借阅信息系统
 
 
 
91.void BookManagemet()
92.{
93.int f = 0;
94.int op;//选择变量
95.book* bookhead;//图书头指针
96.user* userhead;//用户头指针
97.borrow* borrowhead;//借阅头指针
98.srand((unsigned)time(NULL));//随机数
99.bookhead = bookinput(); //读入图书信息
100.userhead = userinput(); //读入用户信息
101.borrowhead = borrowinput();//读入借阅信息
102.while (1)
103.{
104.op = displaymenu();//主菜单
105.switch (op)
106.{
107.case 1:
108.booksysteam(bookhead);
109.break;
110.case 2:
111.usersysteam(userhead);
112.break;
113.case 3:
114.borrowsysteam(borrowhead);
115.break;
116.case 0:
117.saveborrow(borrowhead);
118.savebook(bookhead);
119.saveuser(userhead);
120.f = 1;
121.break;
122.}
123.if (f == 1)
124.break;
125.}
 
 
126.}
 
127.int usermenu()//用户菜单
128.{
129.int op;
130.while (1)
131.{
 
132.system("cls");
133.printf("\n请选择操作:\n");
134.printf("--------------------------------------\n");
135.printf("(1)显示所有用户信息\n");
136.printf("(2)修改用户信息\n");
137.printf("(3)删除用户信息\n");
138.printf("(4)增加用户信息\n");
139.printf("--------------------------------------\n");
140.scanf_s("%d", &op);
141.getchar();
142.printf("\n");
143.if (op < 0 || op  > 4)
144.{
145.printf("\n请选择正确操作");
146.system("pause");
147.}
148.else
149.return op;
150.}
151.}
152.void usercreate(const char* path)//用户信息的建立
153.{
154.FILE* fp;
155.User inf;
156.int i = 1;
157.int ch;
158.errno_t err;
159.if ((err = fopen_s(&fp, path, "w")) != 0)
160.{
161.printf("\n无法建立新文件\n");
162.return;
163.}
164.printf("下面将输入用户信息(姓名输入$,结束):\n");
165.while (1)
166.{
167.printf("\n请输入第%d个用户信息: \n", i++);
168.printf("--------------------------------------\n");
169.printf("姓名(12个字符以内):\t");
170.getchar();
171./*if (i > 1) {
172.scanf_s("%c", &ch);
173.}*/
174.gets_s(inf.name);
175.//inf.name[idlen - 2] = '\0';
176.if (strcmp(inf.name, "$") == 0)
177.{
178.printf("输入用户信息结束! \n");
179.fclose(fp);
180.return;
181.}
182.printf("\n性别:\t");
183.scanf_s("%s", inf.sex, 5);
184.inf.sex[sexlen] = '\0';
185.printf("专业:\t\t");
186.scanf_s("%s", inf.major, 11);
187.inf.major[namelen] = '\0';
188.printf("出生日期:\t");
189.scanf_s("%d", &inf.born);
190.inf.borrowid = rand();
191.printf("该用户的借书证号为:%d", inf.borrowid);
192.printf("\n--------------------------------------\n");
193.fwrite(&inf, sizeof(User), 1, fp);
194.}
195.}
196.user* userimport(FILE* fp)
197.{
198.user* head = NULL, * p, * q = NULL;
199.User inf;
200.fread(&inf, sizeof(User), 1, fp);
201.while (!feof(fp))
202.{
203.if (head == NULL)
204.{
205.head = (user*)malloc(sizeof(user));
206.head->userinf = inf;
207.head->next = NULL;
208.q = head;
209.}
210.else
211.{
212.p = (user*)malloc(sizeof(user));
213.p->userinf = inf;
214.p->next = NULL;
215.q->next = p;
216.q = p;
217.}
218.fread(&inf, sizeof(User), 1, fp);
219.}
220.return head;
221.}
 
 
222.user* userinput()//初始化用户信息
223.{
224.FILE* fp;
225.user* head;
226.errno_t err;
227.if ((err = fopen_s(&fp, userpath, "r")) != 0)
228.{
229.usercreate(userpath);
230.if ((err = fopen_s(&fp, userpath, "rb")) != 0)
231.{
232.printf("无法初始化数据,退出系统!\n");
233.exit(1);
234.}
235.head = userimport(fp);
236.}
237.else
238.head = userimport(fp);
239.fclose(fp);
240.return head;
241.}
242.void displayuser(user* head)//用户信息输出
243.{
244.user* p = head;
245.system("cls");
246.if (head == NULL)
247.{
248.printf("没有用户信息\n");
249.return;
250.}
251.printf("所有用户的信息:\n========================\n");
252.printf("姓名\t性别\t专业\t出生日期\t借书证号\n");
253.printf("--------------------------------------\n");
254.if (p == NULL)
255.return;
256.while (p != NULL)
257.{
258.printf("%s\t%s\t%s\t", p->userinf.name, p->userinf.sex, p->userinf.major);
259.printf("%d\t%d\n", p->userinf.born, p->userinf.borrowid);
260.p = p->next;
261.}
262.printf("--------------------------------------\n");
263.system("pause");
264.}
265.user* finduserName(user* head, char* name)//查询用户名
266.{
267.user* p = head;
268.while (p != NULL && strcmp(p->userinf.name, name) != 0)
269.p = p->next;
270.return p;
271.}
272.int displayuserrenew()//修改用户信息菜单
273.{
274.int op;
275.while (1)
276.{
277.system("cls");
278.printf("\n请选择操作: \n");
279.printf("--------------------------------------\n");
280.printf("(1)修改用户的姓名\n");
281.printf("(2)修改用户的出生日期\n");
 
 
282.printf("--------------------------------------\n");
283.scanf_s("%d", &op);
284.printf("\n");
285.if (op < 0 || op  > 2)
286.{
287.printf("\n请选择正确操作");
288.system("pause");
289.}
290.else
291.return op;
292.}
293.}
294.void renewuser(user* head)//修改用户信息
 
295.{
296.int op;
297.user* p;
298.char name[idlen];
299.system("cls");
300.printf("请输入要修改用户的姓名:\n");
301.gets_s(name);
302.p = finduserName(head, name);
303.if (p == NULL)
304.{
305.printf("\n该用户不存在!\n");
306.system("pause");
307.return;
 
308.}
309.op = displayuserrenew();
 
310.switch (op)
311.{
312.case 1:
313.printf("\n原用户的姓名是: %s\n", p->userinf.name);
314.printf("请输新的姓名:");
315.scanf_s("%d", &p->userinf.name);
316.break;
317.case 2:
318.printf("\n原修改用户的出生日期是:%d\n", p->userinf.born);
319.printf("请输新的出生日期:");
320.scanf_s("%d", &p->userinf.born);
321.break;
 
322.}
323.printf("\n修改完成! \n");
324.system("pause");
325.}
326.void deleteuser(user* head)//删除用户信息
327.{
328.user* p, * q;
329.char name[idlen];
330.system("cls");
331.printf("\n请输入要删除用户的姓名:");
332.gets_s(name);
333.p = finduserName(head, name);
 
334.if (p == NULL)
 
335.{
336.printf("\n要删除的用户不存在! \n");
337.system("pause");
338.return;
339.}
340.else
341.q = p->next;
342.p->userinf = q->userinf;
343.p->next = q->next;
344.free(q);
345.printf("\n删除完成! \n");
346.system("pause");
 
347.}
348.void adduser(user* head)//增加用户信息
349.{
350.User inf;
351.user* p = head;
352.char con = 'Y';
353.int i = 1;
354.while(p->next != NULL) {
355.p = p->next;
356.}
357.while (con == 'Y')
358.{
359.printf("\n请输入第%d个用户信息: \n", i);
360.printf("--------------------------------------\n");
361.printf("姓名(12个字符以内):\t");
362.gets_s(inf.name);
363.inf.name[idlen-2] = '\0';
364.printf("性别:\t");
365.gets_s(inf.sex);
366.inf.sex[sexlen] = '\0';
367.printf("专业:\t\t");
368.gets_s(inf.major);
369.printf("出生日期:\t");
370.scanf_s("%d", &inf.born);
371.inf.major[namelen] = '\0';
372.inf.borrowid = rand();
373.printf("--------------------------------------\n");
374.p->next = (user*)malloc(sizeof(user));
375.p = p->next;
376.p->userinf = inf;
377.p->next = NULL;
378.i++;
379.printf("\n是否继续增加(y/n)?");
380.con = _getche();
381.if (con == 'y')
382.con = con - 32;
383.getchar();
384.}
385.printf("\n添加完成,共添加了%d个\n", i - 1);
386.system("pause");
387.}
388.void saveuser(user* head)//保存用户信息
389.{
390.user* p = head;
391.FILE* fp;
392.errno_t err;
393.if ((err = fopen_s(&fp, userpath, "w")) != 0)
394.{
395.printf("\n建立新文件错误,无法保存\n");
396.return;
397.}
398.while (p != NULL)
399.{
400.fwrite(&p->userinf, sizeof(user), 1, fp);
401.p = p->next;
402.}
403.fclose(fp);
404.printf("\n保存用户信息成功\n");
405.system("pause");
406.}
 
407.void usersysteam(user* userhead) //用户信息系统
408.{
409.int op;
410.op = usermenu();
 
411.switch (op)
412.{
413.case 1:
414.displayuser(userhead);
415.break;
416.case 2:
417.renewuser(userhead);
418.break;
419.case 3:
420.deleteuser(userhead);
421.break;
422.case 4:
423.adduser(userhead);
424.break;
425.}
426.}
427.int borrowmenu()//借阅菜单
428.{
429.int op;
430.while (1)
431.{
 
432.system("cls");
433.printf("\n请选择操作: \n");
434.printf("--------------------------------------\n");
435.printf("(1)显示所有借阅信息\n");
436.printf("(2)修改借阅信息\n");
437.printf("(3)删除借阅信息\n");
438.printf("(4)增加借阅信息\n");
439.printf("--------------------------------------\n");
440.scanf_s("%d", &op);
441.getchar();
442.printf("\n");
443.if (op < 0 || op > 4)
444.{
445.printf("\n请选择正确操作");
446.system("pause");
447.}
448.else
449.return op;
450.}
451.}
452.void borrowcreate(const char* path)
453.{
454.FILE* fp;
455.Bor inf;
456.int i = 1;
457.errno_t err;
458.if ((err = fopen_s(&fp, path, "w")) != 0)
459.{
460.printf("\n无法建立新文件");
461.return;
462.}
463.printf("下面将输入借阅信息(图书编号输入$,结束):\n");
 
464.while (1)
465.{
466.printf("\n请输入第%d个借阅信息: \n", i++);
467.printf("--------------------------------------\n");
468.printf("图书编号(12个字符以内):\t");
469.scanf_s("%s", inf.bookid, idlen);
470.inf.bookid[idlen - 1] = '\0';
471.if (strcmp(inf.bookid, "$") == 0)
472.{
473.printf("输入借阅信息结束! \n");
474.fclose(fp);
475.return;
476.}
477.printf("时间:\t");
478.getchar();
479.gets_s(inf.time);
480.inf.time[idlen] = '\0';
481.inf.ISBN = rand();
482.printf("借书证号:\t");
483.gets_s(inf.borrowid);
484.inf.borrowid[idlen] = '\0';
485.printf("--------------------------------------\n");
486.fwrite(&inf, sizeof(Bor), 1, fp);
487.}
 
488.}
 
489.borrow* borrowimport(FILE* fp)//读取文件的中的借阅信息并且借阅的头指针
490.{
 
491.borrow* head = NULL, * p, * q = NULL;
492.Bor inf;
493.fread(&inf, sizeof(Bor), 1, fp);
494.while (!feof(fp))
495.{
496.if (head == NULL)
497.{
498.head = (borrow*)malloc(sizeof(borrow));
499.head->borrowinf = inf;
500.head->next = NULL;
501.q = head;
 
502.}
503.else
504.{
505.p = (borrow*)malloc(sizeof(borrow));
506.p->borrowinf = inf;
507.p->next = NULL;
508.q->next = p;
509.q = p;
510.}
511.fread(&inf, sizeof(Bor), 1, fp);
512.}
513.return head;
514.}
 
 
515.borrow* borrowinput()//初始化借阅者信息
516.{
517.FILE* fp;
518.borrow* head;
519.errno_t err;
520.if ((err = fopen_s(&fp, borrowpath, "r")) != 0)
521.{
522.borrowcreate(borrowpath);
523.if ((err = fopen_s(&fp, borrowpath, "rb")) != 0)
524.{
525.printf("无法初始化数据,退出系统!\n");
526.exit(1);
527.}
528.head = borrowimport(fp);
529.}
530.else
531.head = borrowimport(fp);
532.fclose(fp);
533.return head;
534.}
535.void displayborrow(borrow* head)//借阅信息输出
536.{
537.borrow* p = head;
538.system("cls");
539.if (head == NULL)
540.{
541.printf("没有借阅信息\n");
542.return;
543.}
544.printf("所有借阅的信息:\n========================\n");
545.printf("图书编号\t借阅时间\t图书证号\tIBSN\n");
546.printf("--------------------------------------\n");
547.while (p != NULL)
548.{
549.printf("%s\t\t%s\t", p->borrowinf.bookid, p->borrowinf.time);
550.printf("%s\t\t%d\n", p->borrowinf.borrowid, p->borrowinf.ISBN);
551.p = p->next;
552.}
553.printf("--------------------------------------\n");
554.system("pause");
555.}
556.borrow* findborrowId(borrow* head, char* id)//查询借阅信息
557.{
558.borrow* p = head;
559.while (p != NULL && strcmp(p->borrowinf.bookid, id) != 0)
560.p = p->next;
561.return p;
562.}
563.int displayborrowrenew()
564.{
565.int op;
566.while (1)
567.{
 
568.system("cls");
569.printf("\n请选择操作: \n");
570.printf("--------------------------------------\n");
571.printf("(1)修改借阅的时间\n");
572.printf("(2)修改借阅的图书号\n");
 
 
573.printf("--------------------------------------\n");
574.scanf_s("%d", &op);
575.printf("\n");
576.if (op < 0 || op > 2)
577.{
578.printf("\n请选择正确操作");
579.system("pause");
580.}
581.else
582.return op;
583.}
584.}
585.void renewborrow(borrow* head)//修改借阅信息
 
586.{
587.int op;
588.borrow* p;
589.char id[idlen];
590.system("cls");
591.printf("请输入要修改借阅的图书编号:\n");
592.gets_s(id);
593.p = findborrowId(head, id);
594.if (p == NULL)
595.{
596.printf("\n该借阅的图书不存在!\n");
597.system("pause");
598.return;
 
599.}
600.op = displayborrowrenew();
 
601.switch (op)
602.{
603.case 1:
604.printf("\n原借阅的时间是: %s\n", p->borrowinf.time);
605.printf("请输新的时间:");
606.getchar();
607.gets_s(p->borrowinf.time);
608.break;
609.case 2:
610.printf("\n原修改借阅的ISBN是:%d\n", p->borrowinf.ISBN);
611.p->borrowinf.ISBN = rand();
612.break;
 
613.}
614.printf("\n修改完成! \n");
615.system("pause");
616.}
617.void deleteborrow(borrow* head)//删除图书信息
618.{
619.borrow* p, * q;
620.char id[idlen];
621.system("cls");
622.printf("\n请输入要删除借阅的图书编号:");
623.gets_s(id);
624.p = findborrowId(head, id);
625.if (p == NULL)
 
626.{
627.printf("\n要删除的借阅不存在! \n");
628.system("pause");
629.return;
630.}
631.else
632.{
633.q = p->next;
634.p->borrowinf = q->borrowinf;
635.p->next = q->next;
636.free(q);
637.printf("\n删除完成! \n");
638.system("pause");
639.}
640.}
641.void addborrow(borrow* head)//增加借阅信息
642.{
643.Bor inf;
644.borrow* p = head;
645.char con = 'Y';
646.int i = 1;
647.while (p->next != NULL)
648.p = p->next;
649.while (con == 'Y')
650.{
651.printf("\n请输入第%d个借阅信息: \n", i);
652.printf("--------------------------------------\n");
653.printf("图书编号(12个字符以内):\t");
654.scanf_s("%s", inf.bookid, idlen);
655.inf.bookid[idlen - 1] = '\0';
656.printf("时间:\t");
657.getchar();
658.gets_s(inf.time);
659.inf.time[idlen - 1] = '\0';
660.inf.ISBN = rand();
661.printf("借书证号:\t");
662.gets_s(inf.borrowid);
663.inf.borrowid[idlen - 1] = '\0';
664.printf("--------------------------------------\n");
665.p->next = (borrow*)malloc(sizeof(borrow));
666.p = p->next;
667.p->borrowinf = inf;
668.p->next = NULL;
669.i++;
670.printf("\n是否继续增加(y/n)?");
671.con = _getche();
672.if (con == 'y')
673.con = con - 32;
 
674.}
675.printf("\n添加完成,共添加了%d个\n", i - 1);
676.system("pause");
677.}
678.void saveborrow(borrow* head)//保存借阅信息
679.{
680.borrow* p = head;
681.FILE* fp;
682.errno_t err = 0;
683.if ((err = fopen_s(&fp, borrowpath, "w")) != 0)
684.{
685.printf("\n建立新文件错误,无法保存\n");
686.return;
687.}
688.while (p != NULL)
689.{
690.fwrite(&p->borrowinf, sizeof(borrow), 1, fp);
691.p = p->next;
692.}
693.fclose(fp);
694.printf("\n保存借阅信息成功\n");
695.system("pause");
696.}
 
697.void borrowsysteam(borrow* borrowhead)//借阅信息系统
698.{
699.int op;
700.op = borrowmenu();
 
701.switch (op)
702.{
703.case 1:
704.displayborrow(borrowhead);
705.break;
706.case 2:
707.renewborrow(borrowhead);
708.break;
709.case 3:
710.deleteborrow(borrowhead);
711.break;
712.case 4:
713.addborrow(borrowhead);
714.break;
715.}
 
716.}
 
717.int bookmenu()//图书菜单
718.{
719.int op;
720.while (1)
721.{
 
722.system("cls");
723.printf("\n请选择操作: \n");
724.printf("--------------------------------------\n");
725.printf("(1)显示所有书籍信息\n");
726.printf("(2)修改书籍信息\n");
727.printf("(3)删除书籍信息\n");
728.printf("(4)增加书籍信息\n");
729.printf("--------------------------------------\n");
730.scanf_s("%d", &op);
731.getchar();
732.printf("\n");
733.if (op < 0 || op > 4)
734.{
735.printf("\n请选择正确操作");
736.system("pause");
737.}
738.else
739.return op;
740.}
741.}
742.void bookcreate(const char* path) //图书信息的创立
743.{
744.FILE* fp;
745.Book inf;
746.int i = 1;
747.errno_t err;
748.if ((err = fopen_s(&fp, path, "w")) != 0)
749.{
750.printf("\n无法建立新文件");
751.return;
752.}
753.printf("下面将输入书籍信息(图书编号输入$,结束):\n");
 
754.while (1)
755.{
756.printf("\n请输入第%d个书籍信息: \n", i++);
757.printf("--------------------------------------\n");
758.printf("图书编号(12个字符以内):\t");
759.scanf_s("%s", inf.bookid, idlen);
760.inf.bookid[idlen] = '\0';
761.if (strcmp(inf.bookid, "$") == 0)
762.{
763.printf("输入书籍信息结束! \n");
764.fclose(fp);
765.return;
766.}
767.printf("书名(%d个字符以内):\t", namelen);
768.getchar();
769.gets_s(inf.name);
770.inf.name[namelen] = '\0';
771.printf("作译者(%d个字符以内):\t", namelen);
772.scanf_s("%s", inf.writer, namelen);
773.inf.writer[namelen] = '\0';
774.printf("出版社:\t\t");
775.getchar();
776.gets_s(inf.press);
777.inf.press[namelen] = '\0';
778.inf.ISBN = rand();
779.printf("价格(整数):\t\t");
780.scanf_s("%d", &inf.price);
781.printf("复本数(整数):\t\t");
782.scanf_s("%d", &inf.bor);
783.printf("库存数(整数):\t\t");
784.scanf_s("%d", &inf.now);
785.printf("--------------------------------------\n");
786.fwrite(&inf, sizeof(Book), 1, fp);
787.}
 
788.}
789.book* bookimport(FILE* fp)//读取文件的中的图书信息并且返回图书的头指针
790.{
791.book* head = NULL, * p, * q = NULL;
792.Book inf;
793.fread(&inf, sizeof(Book), 1, fp);
794.while (!feof(fp))
795.{
796.if (head == NULL)
797.{
798.head = (book*)malloc(sizeof(book));
799.head->bookinf = inf;
800.head->next = NULL;
801.q = head;
 
802.}
803.else
804.{
805.p = (book*)malloc(sizeof(book));
806.p->bookinf = inf;
807.p->next = NULL;
808.q->next = p;
809.q = p;
810.}
811.fread(&inf, sizeof(Book), 1, fp);
812.}
813.return head;
814.}
 
815.book* bookinput()//初始化图书信息
816.{
817.FILE* fp;
818.book* head;
819.errno_t err = 0;
820.if ((err = fopen_s(&fp, bookpath, "r")) != 0)
821.{
822.bookcreate(bookpath);
823.if ((err = fopen_s(&fp, bookpath, "rb")) != 0)
824.{
825.printf("无法初始化数据,退出系统!\n");
826.exit(1);
827.}
828.head = bookimport(fp);
829.}
830.else
831.head = bookimport(fp);
832.fclose(fp);
833.return head;
834.}
835.void displaybook(book* head)//将所有的图书信息输出
836.{
837.book* p = head;
838.system("cls");
839.if (head == NULL)
840.{
841.printf("没有书籍信息\n");
842.return;
843.}
844.printf("所有书籍的信息:\n========================\n");
845.printf("图书编号\t书名\t\t作译者\t出版社\t价格\t复本数\t库存数\tIBSN\n");
846.printf("--------------------------------------\n");
847.while (p != NULL)
848.{
849.printf("%s\t\t%s\t\t%s\t%s\t", p->bookinf.bookid, p->bookinf.name, p->bookinf.writer, &p->bookinf.press);
850.printf("%d\t%d\t%d\t%d\t\n", p->bookinf.price, p->bookinf.bor, p->bookinf.now, p->bookinf.ISBN);
851.p = p->next;
852.}
853.printf("--------------------------------------\n");
854.system("pause");
855.}
856.book* findbookId(book* head, char* id)//查询图书
857.{
858.book* p = head;
859.while (p != NULL && strcmp(p->bookinf.bookid, id) != 0)
860.p = p->next;
861.return p;
862.}
863.int displaybookrenew()//修改图书信息菜单
864.{
865.int op;
866.while (1)
867.{
 
868.system("cls");
869.printf("\n请选择操作: \n");
870.printf("--------------------------------------\n");
871.printf("(1)修改书籍的价格\n");
872.printf("(2)修改书籍的库存数\n");
873.printf("--------------------------------------\n");
874.scanf_s("%d", &op);
875.getchar();
876.printf("\n");
877.if (op < 0 || op > 2)
878.{
879.printf("\n请选择正确操作");
880.system("pause");
881.}
882.else
883.return op;
884.}
885.}
886.void renewbook(book* head)//修改图书信息
 
887.{
888.int op;
889.book* p;
890.char id[idlen];
891.system("cls");
892.printf("请输入要修改书籍的书籍编号:\n");
893.gets_s(id);
894.p = findbookId(head, id);
895.if (p == NULL)
896.{
897.printf("\n该书籍不存在!\n");
898.system("pause");
899.return;
 
900.}
901.op = displaybookrenew();
 
902.switch (op)
903.{
904.case 1:
905.printf("\n原书籍的价格是: %d\n", p->bookinf.price);
906.printf("请输新的价格:");
907.scanf_s("%d", &p->bookinf.price);
908.break;
909.case 2:
910.printf("\n原修改书籍的库存数是:%d\n", p->bookinf.now);
911.printf("请输新的库存数:");
912.scanf_s("%d", &p->bookinf.now);
913.break;
 
914.}
915.printf("\n修改完成! \n");
916.system("pause");
917.}
918.void deletebook(book* head)//删除书籍
919.{
920.book* p, * q;
921.char id[idlen];
922.system("cls");
923.printf("\n请输入要删除书籍的书籍编号:");
924.gets_s(id);
925.p = findbookId(head, id);
926.if (p == NULL)
 
927.{
928.printf("\n要删除的书籍不存在! \n");
929.system("pause");
930.return;
931.}
932.q = p->next;
933.p->bookinf = q->bookinf;
934.p->next = q->next;
935.free(q);
936.printf("\n删除完成!\n");
937.system("pause");
938.}
939.void addbook(book* head)//增加图书信息
940.{
941.Book inf;
942.book* p = head;
943.char con = 'Y';
944.int i = 0;
945.while (p->next != NULL)
946.p = p->next;
947.while (con == 'Y')
948.{
949.printf("\n请输入第%d个书籍信息: \n", i + 1);
950.printf("--------------------------------------\n");
951.printf("图书编号(12个字符以内):\t");
952.scanf_s("%s", inf.bookid, idlen);
953.inf.bookid[idlen - 1] = '\0';
954.printf("书名:\t");
955.getchar();
956.gets_s(inf.name);
957.inf.name[namelen - 1] = '\0';
958.printf("作译者:\t");
959.gets_s(inf.writer);
960.inf.writer[namelen - 1] = '\0';
961.printf("出版社:\t");
962.gets_s(inf.press);
963.inf.press[namelen - 1] = '\0';
964.inf.ISBN = rand();
965.printf("价格(整数):\t\t");
966.scanf_s("%d", &inf.price);
967.printf("复本数(整数):\t\t");
968.scanf_s("%d", &inf.bor);
969.printf("库存数(整数):\t\t");
970.scanf_s("%d", &inf.now);
971.printf("--------------------------------------\n");
972.p->next = (book*)malloc(sizeof(book));
973.p = p->next;
974.p->bookinf = inf;
975.p->next = NULL;
976.i++;
977.printf("\n是否继续增加(y/n)?");
978.con = _getche();
979.if (con == 'y')
980.con = con - 32;
981.}
982.printf("\n添加完成,共添加了%d个\n", i);
983.system("pause");
984.}
985.void savebook(book* head)//保存图书信息
986.{
987.book* p = head;
988.FILE* fp;
989.errno_t err = 0;
990.if ((err = fopen_s(&fp, bookpath, "w")) != 0)
991.{
992.printf("\n建立新文件错误,无法保存\n");
993.return;
994.}
995.while (p != NULL)
996.{
997.fwrite(&p->bookinf, sizeof(Book), 1, fp);
998.p = p->next;
999.}
1000.fclose(fp);
1001.printf("\n保存书籍信息成功\n");
1002.system("pause");
1003.}
1004.void booksysteam(book* bookhead)//图书
1005.{
1006.int op;
1007.op = bookmenu();//图书菜单
1008.switch (op)
1009.{
1010.case 1:
1011.displaybook(bookhead);
1012.break;
1013.case 2:
1014.renewbook(bookhead);
1015.break;
1016.case 3:
1017.deletebook(bookhead);
1018.break;
1019.case 4:
1020.addbook(bookhead);
1021.break;
1022.}
1023.}
1024.int displaymenu()//主菜单
1025.{
1026.int op;
1027.while (1)
1028.{
1029.system("cls");
1030.printf("--------------------------------------\n");
1031.printf("(1)书籍信息\n");
1032.printf("(2)用户信息\n");
1033.printf("(3)借阅信息\n");
1034.printf("(0)退出程序\n");
1035.printf("--------------------------------------\n");
1036.scanf_s("%d", &op);
1037.getchar();
1038.printf("\n");
1039.if (op < 0 || op  > 3)
1040.{
1041.printf("\n请输入正确序号。");
1042.system("pause");
1043.}
1044.else
1045.return op;
1046.}
1047.

程序说明:
核心数据结构:
void BookManagemet();//核心函数
其他解释:
见代码注释

项目扩展

对于程序代码不使用数组,而是使用链表实现程序;上述代码即实现

项目小结

文件名:文件路径+文件名主干+文件后缀,文件路径分为绝对路径和相对路径,两者怎么区分?
绝对路径:以盘符或者根目录开头的如C/D:
相对路径:以.或者…开头的,但是前提是你必须在当前目录下才能谈及相对路径。
以.\开头的表示当前路径,.以…\开头的表示当前路径的上一层路径。

参考文献

叶安胜, 鄢涛. C语言综合项目实战[M]. 科学出版社, 2015.

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值