4.二进制I/O:fread()和fwrite()函数
举个例子:
double num=1./3.;
fprintf("fp,"%f",num);
这个%f可以要求为%.2f或者%.12f,读取文件没有办法恢复其完整的精度。总之,fprintf()函数以一种可能改变数字值的方式将其转化为字符串。
最精确和一致的数字存储方式就是使用与程序所使用的相同位格式,比如一个double类型的值就应该存放在一个double大小的单元里面。如果把数据存储在一个使用与程序相同表示方法的文件中,就称数据以二进制形式存储,这中间没有数字形式到字符串形式的转化。实际上,所有数据都是以二进制的方式进行存储的,甚至连字符也都是使用二进制表示来存储的额。然而,如果文件中的全部数据都以字符编码的形式被解读,那么该文件包含文本数据;如果这些数据的部分或者全部以二进制的数字数据被解读,就称文件包含二进制数据,机器语言指令数据也是二进制文件。
5.size_t fwrite()函数
原型:
fwrite()将二进制数据写进文件。size_t是sizeof运算符返回的类型(通常是unsigned int 类型)。指针ptr是要写入的数据块的地址,size表示要写入的数据块的大小(单位为字节),nmemb表示数据块数目,fp指定要写入的文件。比如要保存一个256字节的数据对象(以数组为例):
char buffer[256];
fwrite(buffer,256,1,fp);
也可以这样:
注意:关于const void * restrict ptr,fwrite()的第一个参数不是固定的类型,比如可以使用字符型的buffer数组指针,可以使用double指针类型的earnings。
fwrite()函数返回成功写入的项目数。正常情况下,这个返回数应该和nmemb大小相等,不过要是写入发生错误的时候,可能这个返回数会小于nmemb的值。
6.size_t fread()函数
原型:
double earnings[10];
fread(earnings,sizeof(double),10,fp);
下面是一个fwrite()函数和fread()函数的例子:
通常我们要实现一些目的,比如:把一系列文件的内容追加到另一些文件的结尾。可以通过交互式将文件信息传到程序中去。
通过以下几个步骤我们将实现目的:
1.请求一个目的文件名,并打开这个文件
2.使用一个循环来请求源文件
3.依次以读取模式打开每一个源文件,同时把它们的内容追加到目的文件
如何打开一个目的文件:
1.以追加模式打开最后一个命令行文件
2.不能成功就退出
3.为这个文件创建一个1024字节的缓冲区
4.如果不能创建就退出
文件复制步骤:
1.如果该文件与目的文件相同,就跳到下一个文件
2.如果不能以读取模式打开,就跳到下一个文件
3.把该文件的内容添加到目的文件中
#include
#include
#include
#define BUFSIZE 1024
#define SLEN 81
void append(FILE *source, FILE *dest);
int main(void)
{
FILE *fa, *fs; //fa指向追加的目的文件,fs指向源文件
int files = 0; //追加文件的个数
char file_app[SLEN];//被追加文件的名称
char file_sou[SLEN];//源文件名称
puts("输入目的文件名:");
gets(file_app);
if ((fa = fopen(file_app, "a")) == NULL)
{
fprintf(stderr, "不能打开文件 %s\n", file_app);
exit(2);
}
if (setvbuf(fa, NULL, _IOFBF, BUFSIZE) != 0) //int setvbuf(FILE * restrict fp,char * restrict buf,int mode,FILE * rescrit ),当buf值为NULL时,此处为目的文件自动创建一个缓冲区,此处完全缓冲,如果不能成功创建,那么程序将终止
{
fputs("不能创建输出缓冲区\n",stderr);
exit(3);
}
puts("输入第一个源文件的名称(空行离开):");
while (gets(file_sou) && file_sou[0] != '\0')
{
if (strcmp(file_sou, filr_app) == 0) //假如file_sou源文件和file_app目的文件一样,此处防止程序将文件追加到自身
fputs("不能附加文件到自身\n", stderr);
else if ((fs = fopen(file_sou), "r") == NULL) //如果不能打开文件
fprintf(stderr, "不能打开文件 %s\n", file_sou);
else
{
if (setvbuf(fs, NULL, _IFFBF, BUFSIZE) != 0) //如果创建fs源文件的缓冲区不成功
{
fputs("不能创建输入缓冲区\n", stderr);
continue;
}
append(fs, fa);
if (ferror(fs) != 0) //读写错误
fprintf(stderr, "读取文件%s错误\n",file_sou);
if (ferror(fa) != 0) //读写错误,ferror()调用成功返回0,不成功读写错误返回非零值
fprintf(stderr, "写入文件%s错误\n", file_app);
fclose(fs);
files++;
prinf("文件%s已添加\n", file_sou);
puts("下一个文件(空行离开):");
}
}
printf("%d文件附加完成\n", files);
fclose(fa);
return 0;
}
void append(FILE *files, FILE *dest)
{
size_t bytes;
static char temp[BUFSIZE]; //分配一次
while ((bytes = fread(temp, sizeof(char), BUDSIZE, source)) > 0)
fwrite(temp, sizeof(char), bytes, dest);
}