10. 错误处理
一般将错误信息写入stderr中,而不是stdout,因为stdout可以重定向,例如:
FILE *fp = NULL;
if ((fp = fopen("test.txt", "r")) == NULL) {
fprintf(stderr, "Can't open file!!!\n");
exit(1);
}
二、二进制流
要指定以二进制模式读写文件,只需要在文件打开模式中加上b,例如rb、wb、rb+。
1. fwrite
函数原型如下:
size_t fwrite(const void *ptr, size_t size, size_t nmemb,
FILE *stream);
fwrite函数并不检查文件是以文本方式还是二进制方式打开,当然也可以使用fwrite将数据写入文本文件中,但是结果会让人很难理解。fwrite实例如下:
FILE *fp = NULL;
int data = 10;
fp = fopen("test", wb);
if (fp != NULL) {
fwrite(&data, sizeof(int), 1, fp);
}
fwrite函数中的参数size为单个元素的字节数,nmemb为元素个数,所以写入的总字节数为size * nmemb。
2. fread
函数原型如下:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
3. 随机访问文件
很多时候,需要随机访问文件中的数据,而不是顺序的访问,这就涉及到修改文件当前的读写位置。需要注意的是,不能在追加模式下修改写操作的位置,因为数据总是写到文件的末尾,可以修改读操作的位置。
(1) ftell
ftell函数返回当前读写操作的位置,函数原型如下:
long ftell(FILE *stream);
(2) fgetpos
fgetpos同ftell函数是相同的作用,都是返回当前的读写操作位置,函数原型如下:
int fgetpos(FILE *stream, fpos_t *pos);
同ftell函数不同的是,读写的位置是存储在参数pos中的,成功返回0,失败返回非0值,例如:
fpos_t here = 0;
fgetpos(fp, &here);
(3) fsetpos
同fgetpos函数对应的是fsetpos,函数原型如下:
int fsetpos(FILE *stream, fpos_t *pos);
fsetpos只能和fgetpos配合使用,也就是说只能使用fgetpos得到的值作为其中的pos参数,例如:fsetpos(fp, &here);
同fgetpos一样,成功返回0,失败返回非0值。
(4) fseek
同ftell函数对应的是fseek,函数原型如下:
int fseek(FILE *stream, long offset, int whence);
第一个参数为文件指针,第二个参数为相对第三个参数的偏移,第三个参数为起始位置,取值有:SEEK_SET、SEEK_CUR和SEEK_END,分别表示文件的开头,当前位置和文件末尾。