在上篇文章中介绍了fgets、gets、fputs、fread等函数如果调用失败则会返回EOF,但是由于EOF即用于报告文件结束,又用于报告随机出现的错误,因此,为了区分究竟是错误返回还是文件结束返回,有时还需要调用ferror函数来确定是否出现错误,调用feof函数检查是否遇到文件结束。
流读取的文档链接:https://blog.csdn.net/weixin_45676049/article/details/109002860
一、流的出错处理
在大多数应用中,Linux内核都为流(FILE)对像提供了两个标志符。
- 出错标志:当读写文件出错时该指示器被设置为真(非0);当没有出错时设置为假(0)。
- 文件结束标志:当已经达到文件末尾时,该指示器被设置为真(非0)。
Linux内核同样提供了ferror 和 feof 函数用于经检查这两个标志符,对其标准调用格式说明如下:
#include <stdio.h>
int ferror(FILE *stream);
int feof(FILE *stream));
feof函数和ferror函数的参数都是一个指定的流指针,如果其测试标志位为真(非0)则返回非零值,否则返回0.。
在确定了错误之后,可以调用clearerr函数来清楚错误,对其标准调用格式说明如下(其参数是需要清楚错误的流对应的指针,没有返回值。):
#include <stdio.h>
void clearerr(FILE *stream);
二、函数使用案例
案例描述:应用代码对一个空文件进行读操作,此时会返回一个EOF错误标志,调用feof函数和ferror函数判断到底是到了文件末尾还是出现错误,然后从往文件里面写入一个字符串后再次判断。
// 判断是到了文件的结尾还是出错
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
int fd;
FILE *fp;
if(argc != 2){
printf("Please input the current para!\n");
return -1;
}
// 使用fopen函数打开argv[1]指定的文件
// 使用w+或者a+都可以,且使用该命令时如果文件不存在则会自动创建
fp = fopen(argv[1], "w+");
// 使用fgetc获取字符,如果文件为空,则会报错
fd = fgetc(fp);
//fputc(fd, stdout);
// 使用ferror函数判断错误类型
printf("ferror的返回值为%d\n ", ferror(fp));
// 在文件末尾写入字符串
fputs("Hello!This is a String!\n",fp);
// 关闭文件
fclose(fp);
// 以只读方式打开文件
fp = fopen(argv[1], "r");
// 使用fseek函数定位至文件末尾
fseek(fp, 0, SEEK_END);
fgetc(fp);
if(feof(fp) == 1){
printf("到达文件末尾!\n");
}
// 清楚当前的错误
clearerr(fp);
printf("ferror的返回值为%d\n", ferror(fp));
printf("feof的返回值为%d\n", feof(fp));
fclose(fp);
return 0;
}
保存文件后,进行编译链接生成可执行文件。其结果为:
参考文献:程国钢, 张玉兰. Linux C编程从基础到实践, 清华大学出版社, 2015.