示例
#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;
}
运行测试
再次运行程序
生成的二进制文件
除文本以外的数据显示为乱码