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
相关文章推荐
- fgets()函数和sscanf()函数的使用方法
- fgets函数
- jQuery 参考手册3-jQuery 效果函数
- C语言速成手册(五):其它运算符、文件操作、其它函数
- 如何使用fgets函数代替gets
- xdebug中文手册之相关函数
- 【JNI】jni.h函数详解手册--The Java(TM) Native Interface
- 转载:C函数手册(1)分类函数->ctype.h
- [转] PostgreSQL学习手册(函数和操作符)
- PHP OPENSSL 函数手册翻译备查 -- openssl_pkey_get_public
- glib 函数api查询入口———参考手册
- Matlab的Signal Processing Toolbox函数速查手册
- 完全详解fgets()函数!
- hive函数参考手册
- PHP - Manual手册 - XXXIII. Error Handling and Logging Functions错误处理和日志函数 - 概述
- 几个函数的问题 的深究fgets
- PHP - Manual手册 - V. Array 数组函数 - array_multisort对多个数组或多维数组进行排序
- Hive函数参考手册
- hive函数参考手册
- DedeCms参考手册、函数及文件大全