首先要知道我们所期望的程序有什么功能?
1.录入图书
2.保存录入图书的数据
3.在下次打开文件时加载已经导入的图书数据
首相我们建立一下程序的大致框架
1.创建一个图书的模板,并创建图书数组。相信这个并不难
struct book { char title[MAXTITL]; char author[MAXAUTL]; float value; };
2.创建一个输入的函数,要求将换行符换成 “\0” 如果不正常输入返回NULL值
3.若已存在数据,则输出已有数据
4.创建循环:持续录入信息
5.将所有结构写入数据到文件
现在开始设计一个输入的函数s_gets()
我们要将内容从stdin存入数组之中,那么参数应该写:
char* s_gets(char* st, int n)
然后开始获取内容
fgets(st, n, stdin);
如果用户不输入值,我们想让函数返回null值,那么实际就是fgets返回的null值。考虑到我们要在函数中对数组进行去回车的处理,所以要用一个变量存储fgets的返回值(fgets返回的是一个指针)
char* s_gets(char* st, int n) { char* ret_val; ret_val = fgets(st, n, stdin); return ret_val; }
接着进行去换行符的操作,我们可以用到 strchr() 函数,strchr可以返回匹配指定符号内容的指针。用法为strchr(处理的数组,匹配的内容),我们可以创建一个变量find去接收它,然后替换\n
char* s_gets(char* st, int n) { char* ret_val; char* find; ret_val = fgets(st, n, stdin); if (ret_val) { find=strchr(st, '\n'); if (find) *find = '\0'; } return ret_val; }
接下来我们来实现录入数据并储存
首先创建一个book的数组,以count进行编号,每录入一次就有count++
录入就会用到循环,那么循环的条件改是什么呢?
1.用户不输入新的书名,既书名时‘\n’时退出循环
2.书本书超过设定的大小
那么条件应该为
while (count<MAXBKS && s_gets(lib[count].title, MAXTITL)!=NULL&&lib[count].title[0]!='\0') {、、、}
注意s_gets函数会将\n替换为\0
然后就是录入
puts("enter the book"); while (count<MAXBKS&& s_gets(lib[count].title, MAXTITL)!=NULL&&lib[count].title[0]!='\0') { puts("Enter the auther"); s_gets(lib[count].author, MAXAUTL); puts("Enter the value"); fscanf(stdin, "%f", &lib[count++].value); //书本书加一 while (getchar() != '\n')continue; if (count<MAXBKS)puts("enter the book"); }
递增书本的时候可以将count++单独写出来,也可以直接在数组内执行
然后就是录入:录入条件肯定是输入了书本书,既count>0,然后用fwrite写入
if (count>0) { puts("here is your book"); for (size_t i = 0; i < count; i++)printf("%s ,%s, %f\n", lib[i].title, lib[i].author, lib[i].value); fwrite(&lib, sizeof(struct book), count, pbooks); }
最后我们来实现从文件中读取数据:
1.将文件中的数据读取并打印出来
我们要解决判断文件中有没有数据的问题,再就是将数据写入数组后才能输出的问题
如何判断有没有数据,既通过fread返回值来判断:有数据则返回1
既然我们设置了图书总量的限制,那么我们也要统计已有图书的个数,那么每次就读入1本图书的数据,然后用count进行统计
while (count<MAXBKS&&fread(&lib[count],sizeof(struct book),1,pbooks)==1) { if (count==0)puts("currents books"); //只需要让这个显示1次 printf("%s ,%s, %f\n", lib[count].title, lib[count].author, lib[count].value); count++; }
于是程序有了新的变动,因为改变了count的初始值。之前我们设置的将书本写入文件的数量就用到了count,那么就需要减去文件中的count数,最终结果为
/* booksave.c -- saves structure contents in a file */ #pragma warning(disable:4996) #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXTITL 40 #define MAXAUTL 40 #define MAXBKS 10 char* s_gets(char* st, int n);
//创建图书信息模板 struct book { char title[MAXTITL]; char author[MAXAUTL]; float value; }; int main(void) { struct book lib[MAXBKS]; FILE* pbooks; int count=0; //打开文件 if ((pbooks = fopen("book.txt", "a+")) == NULL) { printf("erro!"); exit(1); } //判断并打印文件中已有的图书数据 while (count<MAXBKS&&fread(&lib[count],sizeof(struct book),1,pbooks)==1) { if (count==0)puts("currents books"); printf("%s ,%s, %f\n", lib[count].title, lib[count].author, lib[count].value); count++; } //获取已存在图书数量 int fcount = count;
//录入图书 puts("enter the book"); while (count<MAXBKS&& s_gets(lib[count].title, MAXTITL)!=NULL&&lib[count].title[0]!='\0') { puts("Enter the auther"); s_gets(lib[count].author, MAXAUTL); puts("Enter the value"); fscanf(stdin, "%f", &lib[count++].value); while (getchar() != '\n')continue; if (count<MAXBKS)puts("enter the book"); }
//储存图书 if (count>0) { puts("here is your book"); for (size_t i = 0; i < count; i++)printf("%s ,%s, %f\n", lib[i].title, lib[i].author, lib[i].value); fwrite(&lib, sizeof(struct book), count-fcount, pbooks); //减去已有数量 fclose(pbooks); } return 0; } char* s_gets(char* st, int n) { char* ret_val; char* find; ret_val = fgets(st, n, stdin); if (ret_val) { find=strchr(st, '\n'); if (find){*find = '\0';} } return ret_val; }
标签:count,val,ret,C语言,char,book,录入,程序设计,st From: https://www.cnblogs.com/kitcat/p/16849046.html