将晦涩难懂的技术讲的通俗易懂
分类: LINUX
2015-01-09 23:27:27
在使用fgets函数读文件时发现每次最后一行都会重复读一遍,程序如下:
#include
#include
int main()
{
FILE *fp;
char ch[128];
fp = fopen("a.txt","r");
while(!feof(fp))
{
fgets((char *)ch, sizeof(ch)-1, fp);
printf("%s",ch);
}
fclose(fp);
}
其中a.txt文件内容如图1所示。
图1
运行程序结果如图2所示。
图2
要想知道为什么最后一行会重复输出,需要知道以下两点:
l feof()只有在你尝试读取文件结尾之后,才会返回true。也就是说,feof()只解释上次文件读写是否到达结尾,而不是下一次。
l fgets()每次读一行,也就是直到读到换行符或者文件结尾才返回,注意如果有换行符,fgets()会连同换行符读入。
下面分析一下上面程序的执行过程:
(1) 判断是否读到了文件结尾(否);
(2) 读取一行”aaaaaaaaaaaaaaaaaaaa\n”,输出;
(3) 判断是否读到了文件结尾(否);
(4) 读取一行”bbbbbbbbbbbbbbbbbb\n”,输出;
(5) 判断是否读到了文件结尾(否);
(6) 读到了文件结尾返回,注意本次没用从文件中读到任何东西,所以字符串ch中保存的还是原来第(4)步读到的内容。所以又将”bbbbbbbbbbbbbbbbbb\n”再次输出。
(7) 判断是否读到了文件结尾(是);
(8) 结束循环。
如果将a.txt的内容换做图3所示,即第二行后没有回车。
图3
再次运行程序输出如图4:
图4
过程分析:
(1) 判断是否读到了文件结尾(否);
(2) 读取一行”aaaaaaaaaaaaaaaaaaaa\n”,输出;
(3) 判断是否读到了文件结尾(否);
(4) 读取”bbbbbbbbbbbbbbbbbb”,注意这里没有换行,所以fgets()一直读到了文件结尾。输出。
(5) 判断是否读到了文件结尾(是);
(6) 结束循环。
l 补充:
1. 使用vim编辑文件保存时会默认在末尾添加一个换行符。如何如图5所示在vim输入数据。
图5
使用editplus打开情况如图6所示:
图6
2. 使用重定向生成的文件同样会在末尾添加换行。如执行ls > b.txt,使用vim打开b.txt如图7.
图7
使用editplus打开b.txt如图8。
图8
同样在结尾添加了一个换行。