您的位置:首页 > 其它

fgets函数手册误我

2017-07-21 11:36 267 查看


fgets函数手册误我


找茬

大家先看一段代码,找找找茬,看看下面的代码有问题没:
1.    while(!feof(fp))
2.    {
3.        memset(buff, 0x0, BUF_SIZE);
4.        if(!fgets(buff, BUF_SIZE, fp))
5.        {
6.            fprintf(stderr, "fgets error: %m\n");
7.            goto err;
8.        }
9.
10.        deal_line(buff, BUF_SIZE);
11.    }


fgets返回值

在我比较喜欢的速查手册(linuxC函数手册.chm)里面是这样子的
若成功则返回s指针, 返回NULL则表示有错误发生。
,所以我在外面做了feof的循环判断,fgets返回空则认为失败。当然这个描述是错误的
man fgets是这样描述的
fgets() returns s on success, and NULL on error or
when end of file occurs while no characters have been read.
,表明没有数据可读时也返回NULL。
上面的代码在文件末有一个换行符时会出现问题,出现报错。

过程是这样:fgets读最后一行数据时,发现’\n’换行符,然后返回(注意:这时文件的所有字符已经读完),进入feof循环判断,此时EOF标志位还未设置(后面会说何时设置),因此返回0,然后继续进行fgets,然后fgets已无数据可读,会返回NULL表示文件已读完。


EOF究竟是啥

我们一般模糊的知道读文件时如果文件已读完就会返回EOF,可以通过feof函数来判断是否读完。当然我们也见过这种代码:
while((c=getchar())!=
EOF)
,因此有人认为文件最后面有一个EOF字符,没数据读时就会读到这个字符。
实际上EOF是一个宏,一般被定义为(int)-1,只有调用fgetc、getc读单个字符的函数时才会遇上返回EOF的情况,正因为如此fgetc、getc的返回值为int型。
而feof函数的实现不是说去读一个字符,如果读到EOF则认为文件读完,如果不是再把这个字符放回缓冲区。feof实际上只是判断了一下文件的EOF标志,那么这个标志什么时候设置的呢,就是C库实现的最后一层read系统调用返回0的时候,设置EOF标志。所以一般情况下,EOF标志会在数据读完的下一次读数据时被设置。
再来分析下前面的代码为什么在文件末尾没有换行符的时候就不会有问题。这和fgets的实现有关,里面用fgetc实现,一直读到换行符或者文件结束,所以在读完最后字符时已经多读了一次返回EOF才结束,此时EOF标志已经设置生效,所以程序会在feof循环处跳出。


修复代码

1.    while(fgets(buff, BUF_SIZE, fp))
2.    {
3.        deal_line(buff, BUF_SIZE);
4.        memset(buff, 0x0, BUF_SIZE);
5.    }
6.
7.    if(!feof(fp))
8.    {
9.        fprintf(stderr, "fgets error: %m\n");
10.            goto err;
11.    }


%23%23%23%20fgets%u51FD%u6570%u624B%u518C%u8BEF%u6211%20%20%0A@%28C%u7F16%u7A0B%29%5Bc%u8BED%u8A00%u7F16%u7A0B%2C%20%u5DE5%u4F5C%u7B14%u8BB0%5D%0A%0A%23%23%23%23%20%u627E%u832C%0A%u5927%u5BB6%u5148%u770B%u4E00%u6BB5%u4EE3%u7801%uFF0C%u627E%u627E%u627E%u832C%uFF0C%u770B%u770B%u4E0B%u9762%u7684%u4EE3%u7801%u6709%u95EE%u9898%u6CA1%3A%0A%60%60%60c%0A%20%20%20%20while%28%21feof%28fp%29%29%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20memset%28buff%2C%200x0%2C%20BUF_SIZE%29%3B%0A%20%20%20%20%20%20%20%20if%28%21fgets%28buff%2C%20BUF_SIZE%2C%20fp%29%29%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20fprintf%28stderr%2C%20%22fgets%20error%3A%20%25m%5Cn%22%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20goto%20err%3B%0A%20%20%20%20%20%20%20%20%7D%0A%09%09%0A%20%20%20%20%20%20%20%20deal_line%28buff%2C%20BUF_SIZE%29%3B%0A%20%20%20%20%7D%0A%60%60%60%0A%0A%23%23%23%23%20fgets%u8FD4%u56DE%u503C%20%20%0A%u5728%u6211%u6BD4%u8F83%u559C%u6B22%u7684%u901F%u67E5%u624B%u518C%uFF08linuxC%u51FD%u6570%u624B%u518C.chm%uFF09%u91CC%u9762%u662F%u8FD9%u6837%u5B50%u7684%60%u82E5%u6210%u529F%u5219%u8FD4%u56DEs%u6307%u9488%2C%20%u8FD4%u56DENULL%u5219%u8868%u793A%u6709%u9519%u8BEF%u53D1%u751F%u3002%60%uFF0C%u6240%u4EE5%u6211%u5728%u5916%u9762%u505A%u4E86feof%u7684%u5FAA%u73AF%u5224%u65AD%uFF0Cfgets%u8FD4%u56DE%u7A7A%u5219%u8BA4%u4E3A%u5931%u8D25%u3002**%u5F53%u7136%u8FD9%u4E2A%u63CF%u8FF0%u662F%u9519%u8BEF%u7684**%u3002%0A%0Aman%20fgets%u662F%u8FD9%u6837%u63CF%u8FF0%u7684%60fgets%28%29%20returns%20s%20on%20success%2C%20and%20NULL%20on%20error%20or%20when%20end%20of%20file%20occurs%20while%20no%20characters%20have%20been%20read.%60%uFF0C%u8868%u660E%u6CA1%u6709%u6570%u636E%u53EF%u8BFB%u65F6%u4E5F%u8FD4%u56DENULL%u3002%0A%0A%u4E0A%u9762%u7684%u4EE3%u7801%u5728%u6587%u4EF6%u672B%u6709%u4E00%u4E2A%u6362%u884C%u7B26%u65F6%u4F1A%u51FA%u73B0%u95EE%u9898%uFF0C%u51FA%u73B0%u62A5%u9519%u3002%0A%u8FC7%u7A0B%u662F%u8FD9%u6837%uFF1Afgets%u8BFB%u6700%u540E%u4E00%u884C%u6570%u636E%u65F6%uFF0C%u53D1%u73B0%27%5Cn%27%u6362%u884C%u7B26%uFF0C%u7136%u540E%u8FD4%u56DE%28%u6CE8%u610F%uFF1A%u8FD9%u65F6%u6587%u4EF6%u7684%u6240%u6709%u5B57%u7B26%u5DF2%u7ECF%u8BFB%u5B8C%29%uFF0C%u8FDB%u5165feof%u5FAA%u73AF%u5224%u65AD%uFF0C%u6B64%u65F6EOF%u6807%u5FD7%u4F4D%u8FD8%u672A%u8BBE%u7F6E%uFF08%u540E%u9762%u4F1A%u8BF4%u4F55%u65F6%u8BBE%u7F6E%uFF09%uFF0C%u56E0%u6B64%u8FD4%u56DE0%uFF0C%u7136%u540E%u7EE7%u7EED%u8FDB%u884Cfgets%uFF0C%u7136%u540Efgets%u5DF2%u65E0%u6570%u636E%u53EF%u8BFB%uFF0C%u4F1A%u8FD4%u56DENULL%u8868%u793A%u6587%u4EF6%u5DF2%u8BFB%u5B8C%u3002%0A%0A%23%23%23%23%20EOF%u7A76%u7ADF%u662F%u5565%20%20%0A%u6211%u4EEC%u4E00%u822C%u6A21%u7CCA%u7684%u77E5%u9053%u8BFB%u6587%u4EF6%u65F6%u5982%u679C%u6587%u4EF6%u5DF2%u8BFB%u5B8C%u5C31%u4F1A%u8FD4%u56DEEOF%uFF0C%u53EF%u4EE5%u901A%u8FC7feof%u51FD%u6570%u6765%u5224%u65AD%u662F%u5426%u8BFB%u5B8C%u3002%u5F53%u7136%u6211%u4EEC%u4E5F%u89C1%u8FC7%u8FD9%u79CD%u4EE3%u7801%uFF1A%60%20while%28%28c%3Dgetchar%28%29%29%21%3D%20EOF%29%60%uFF0C%u56E0%u6B64%u6709%u4EBA%u8BA4%u4E3A%u6587%u4EF6%u6700%u540E%u9762%u6709%u4E00%u4E2AEOF%u5B57%u7B26%uFF0C%u6CA1%u6570%u636E%u8BFB%u65F6%u5C31%u4F1A%u8BFB%u5230%u8FD9%u4E2A%u5B57%u7B26%u3002%0A%0A%u5B9E%u9645%u4E0AEOF%u662F%u4E00%u4E2A%u5B8F%uFF0C%u4E00%u822C%u88AB%u5B9A%u4E49%u4E3A%28int%29-1%uFF0C%u53EA%u6709%u8C03%u7528fgetc%u3001getc%u8BFB%u5355%u4E2A%u5B57%u7B26%u7684%u51FD%u6570%u65F6%u624D%u4F1A%u9047%u4E0A%u8FD4%u56DEEOF%u7684%u60C5%u51B5%uFF0C%u6B63%u56E0%u4E3A%u5982%u6B64fgetc%u3001getc%u7684%u8FD4%u56DE%u503C%u4E3Aint%u578B%u3002%0A%0A%u800Cfeof%u51FD%u6570%u7684%u5B9E%u73B0%u4E0D%u662F%u8BF4%u53BB%u8BFB%u4E00%u4E2A%u5B57%u7B26%uFF0C%u5982%u679C%u8BFB%u5230EOF%u5219%u8BA4%u4E3A%u6587%u4EF6%u8BFB%u5B8C%uFF0C%u5982%u679C%u4E0D%u662F%u518D%u628A%u8FD9%u4E2A%u5B57%u7B26%u653E%u56DE%u7F13%u51B2%u533A%u3002feof%u5B9E%u9645%u4E0A%u53EA%u662F%u5224%u65AD%u4E86%u4E00%u4E0B%u6587%u4EF6%u7684EOF%u6807%u5FD7%uFF0C%u90A3%u4E48%u8FD9%u4E2A%u6807%u5FD7%u4EC0%u4E48%u65F6%u5019%u8BBE%u7F6E%u7684%u5462%uFF0C%u5C31%u662FC%u5E93%u5B9E%u73B0%u7684%u6700%u540E%u4E00%u5C42read%u7CFB%u7EDF%u8C03%u7528%u8FD4%u56DE0%u7684%u65F6%u5019%uFF0C%u8BBE%u7F6EEOF%u6807%u5FD7%u3002%u6240%u4EE5%u4E00%u822C%u60C5%u51B5%u4E0B%uFF0CEOF%u6807%u5FD7%u4F1A%u5728%u6570%u636E%u8BFB%u5B8C%u7684%u4E0B%u4E00%u6B21%u8BFB%u6570%u636E%u65F6%u88AB%u8BBE%u7F6E%u3002%0A%0A%u518D%u6765%u5206%u6790%u4E0B%u524D%u9762%u7684%u4EE3%u7801%u4E3A%u4EC0%u4E48%u5728%u6587%u4EF6%u672B%u5C3E%u6CA1%u6709%u6362%u884C%u7B26%u7684%u65F6%u5019%u5C31%u4E0D%u4F1A%u6709%u95EE%u9898%u3002%u8FD9%u548Cfgets%u7684%u5B9E%u73B0%u6709%u5173%uFF0C%u91CC%u9762%u7528fgetc%u5B9E%u73B0%uFF0C%u4E00%u76F4%u8BFB%u5230%u6362%u884C%u7B26%u6216%u8005%u6587%u4EF6%u7ED3%u675F%uFF0C%u6240%u4EE5%u5728%u8BFB%u5B8C%u6700%u540E%u5B57%u7B26%u65F6%u5DF2%u7ECF%u591A%u8BFB%u4E86%u4E00%u6B21%u8FD4%u56DEEOF%u624D%u7ED3%u675F%uFF0C%u6B64%u65F6EOF%u6807%u5FD7%u5DF2%u7ECF%u8BBE%u7F6E%u751F%u6548%uFF0C%u6240%u4EE5%u7A0B%u5E8F%u4F1A%u5728feof%u5FAA%u73AF%u5904%u8DF3%u51FA%u3002%0A%0A%23%23%23%23%20%u4FEE%u590D%u4EE3%u7801%0A%60%60%60c%20%0A%09while%28fgets%28buff%2C%20BUF_SIZE%2C%20fp%29%29%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20deal_line%28buff%2C%20BUF_SIZE%29%3B%0A%20%20%20%20%20%20%20%20memset%28buff%2C%200x0%2C%20BUF_SIZE%29%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%28%21feof%28fp%29%29%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20fprintf%28stderr%2C%20%22fgets%20error%3A%20%25m%5Cn%22%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20goto%20err%3B%0A%20%20%20%20%7D%0A%60%60%60%0A
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  fget EOF