示例
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> #define MAXTITL 40 #define MAXAUTL 40 #define MAXBKS 10 struct book { char title[MAXTITL]; char author[MAXAUTL]; float value; }; char * s_gets(char * st, int n); int main(int argc, char* argv[]) { struct book library[MAXBKS]; //结构数组 int count = 0; int index, filecount; FILE* pbooks; int size = sizeof(struct book); /* 以a+b模式打开文件,a+部分允许程序读取整个文件并在文件的末尾添加内容。b是ANSI 的一种标识方法,表明程序将使用二进制文件格式。对于不接受b模式的UNIX系统,可以省略b,因为 UNIX只是一种文件形式。对于早期的ANSI实现,要找出和b等价的表示法。 之所以选择二进制模式是因为fread()和fwrite()函数要使用二进制文件。虽然结构中有些内容是文本, 但是value成员不是文本。如果使用文本编辑器查看book.dat,该结构文本部分的内容显示正常,但是 数值部分的内容不可读,甚至会导致文本编辑器出现乱码。 rewrite()函数确保文件指针位于文件开始处,为读文件做好准备。 */ if ((pbooks = fopen("book.dat", "a+b")) == NULL) { fputs("Can't open book.dat file\n", stderr); exit(1); } rewind(pbooks); /* 定位到文件开始位置 */ /* 每次把一个结构读到结构数组中,当数组已满或读完文件时停止 fread(元素位置地址,数据块大小,每次读几块数据, 文件指针) : 返回成功读取的数据块数量 */ while (count < MAXBKS && fread(&library[count], size, 1, pbooks) == 1) { if (count == 0) puts("Current contents of book.dat:"); printf("%s by %s: $%.2f\n", library[count].title, library[count].author, library[count].value); count++; } filecount = count; if (count == MAXBKS) { fputs("The book.dat file is full.", stderr); exit(2); } puts("Please add new book titles."); puts("Press [enter] at the start of a line to stop."); while (count < MAXBKS && s_gets(library[count].title, MAXTITL) != NULL && library[count].title[0] != '\0') { puts("Now enter the author."); s_gets(library[count].author, MAXAUTL); puts("Now enter the value."); scanf("%f", &library[count++].value); while (getchar() != '\n') continue; //清理输入行 if (count < MAXBKS) puts("Enter the next title."); } if (count > 0) { puts("Here is the list of your books:"); for (index = 0; index < count; index++) printf("%s by %s: $%.2f\n", library[index].title, library[index].author, library[index].value); fwrite(&library[filecount], size, count - filecount, pbooks); } else puts("No books? Too bad.\n"); puts("Bye.\n"); fclose(pbooks); system("pause"); return 0; } // 自己实现读取函数 char* s_gets(char* st, int n) { char* ret_val; int i = 0; ret_val = fgets(st, n, stdin); if (ret_val) //即,ret_val != NULL { while (st[i] != '\n' && st[i] != '\0') i++; if (st[i] == '\n') st[i] = '\0'; else while (getchar() != '\n') continue; } return ret_val; }
运行测试
再次运行程序
生成的二进制文件
除文本以外的数据显示为乱码