免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 封神
打印 上一主题 下一主题

求助-读取文件出错,最后一行重复输出[已解决-都是feof惹的祸] [复制链接]

论坛徽章:
0
11 [报告]
发表于 2007-07-03 08:44 |只看该作者
这个不是漏洞,
只是多少有些容易产生误导

原帖由 封神 于 2007-7-3 08:38 发表
这个不算是漏洞么?

论坛徽章:
0
12 [报告]
发表于 2007-07-03 08:52 |只看该作者
原帖由 封神 于 2007-7-2 20:25 发表
写了一个程序,可以格式化的从文件中读出自己想要的字段,然后分别显示在屏幕上,虽然方法可能傻了点,不过还算好用,后来在测试的时候,突然发现了一个问题,不知道为什么,当文件读到最后时,并没有结束,而是将最后一行字 ...


while (!feof(fp)) {
  buf[0] = 0x00;
  fgets(buf, sizeof buf, fp);
  if (buf[0] == 0x00)
     break;  // ferror(fp) 或者 feof(fp)
  ...
}
if (ferror(fp)) { // 对应break出错时候蹦出来的情况
   
}


当然,还是像他们说的一样,直接fgets放在while 里最好了,没有必要的。

[ 本帖最后由 ivhb 于 2007-7-3 08:53 编辑 ]

论坛徽章:
0
13 [报告]
发表于 2007-07-03 09:09 |只看该作者
收到,谢了

论坛徽章:
0
14 [报告]
发表于 2007-07-03 09:28 |只看该作者
原帖由 ivhb 于 2007-7-3 08:52 发表


while (!feof(fp)) {
  buf[0] = 0x00;
  fgets(buf, sizeof buf, fp);
  if (buf[0] == 0x00)
     break;  // ferror(fp) 或者 feof(fp)
  ...
}
if (ferror(fp)) { // 对应break出错时候蹦出来的情 ...


没有测试过你的程序,但是感觉有问题。

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
15 [报告]
发表于 2007-07-03 09:38 |只看该作者
原帖由 封神 于 2007-7-3 08:38 发表
这个不算是漏洞么?

也许在设计之初算是,但是现在这个已经写入标准,那么就不再是 bug,而是标准了

论坛徽章:
0
16 [报告]
发表于 2007-07-03 12:25 |只看该作者
原帖由 福瑞哈哥 于 2007-7-3 09:28 发表


没有测试过你的程序,但是感觉有问题。



:) 如果是磁盘文件来说,这么做不会有什么问题。
因为磁盘文件,ferror几乎不可能为错。只要你打开成功的话。
对于ferror来说,因为没有规定
fgets失败,buf是否会被复写。因此这个是未定义的。
但是到达文件结束,buf会left unchanged。
因此,这么做几乎是等价的吧。

论坛徽章:
0
17 [报告]
发表于 2007-07-03 15:06 |只看该作者
最终选择在while中写fgets,对于我个人来说比较好理解,再次谢谢大家。



原帖由 MMMIX 于 2007-7-3 09:38 发表

也许在设计之初算是,但是现在这个已经写入标准,那么就不再是 bug,而是标准了



强权标准啊,根本就不好用,还要强迫大家接受,修正这么一个函数又不会死人,真不知道为什么那些家伙不改

论坛徽章:
0
18 [报告]
发表于 2007-07-03 16:10 |只看该作者
LZ,你应该判断fgets()为NULL,不判断而继续使用buf的内容,自己的程序是不对的。

foef(stream)针对的是”流“, 用一个indicator(指示)表明文件尾,而feof判断这个指示是否设置,而不是判断当前SEEK数值是否到尾。
seek值到尾了对于“流”不一定是是文件尾,因为“流”是会不断增长的。比如pipe, sockfd等。

不是BUG,不要想象这么多年了编制库函数的人都愚不可及。


NAME
       clearerr, feof, ferror, fileno - check and reset stream status

SYNOPSIS
       #include <stdio.h>

       void clearerr(FILE *stream);
       int feof(FILE *stream);
       int ferror(FILE *stream);
       int fileno(FILE *stream);

DESCRIPTION
       The function clearerr clears the end-of-file and error indicators for the stream pointed to by stream.

       The  function  feof tests the end-of-file indicator for the stream pointed to by stream, returning non-zero if it is
       set.  The end-of-file indicator can only be cleared by the function clearerr.

       The function ferror tests the error indicator for the stream pointed to by stream, returning non-zero if it is  set.
       The error indicator can only be reset by the clearerr function.

       The function fileno examines the argument stream and returns its integer descriptor.

       For non-locking counterparts, see unlocked_stdio(3).

ERRORS
       These  functions  should not fail and do not set the external variable errno.  (However, in case fileno detects that
       its argument is not a valid stream, it must return -1 and set errno to EBADF.)

CONFORMING TO
       The functions clearerr, feof, and ferror conform to X3.159-1989 (鈥樷€楢NSI C鈥欌€?.

SEE ALSO
       open(2), unlocked_stdio(3), stdio(3)

论坛徽章:
0
19 [报告]
发表于 2007-07-03 16:48 |只看该作者
原帖由 思一克 于 2007-7-3 16:10 发表
LZ,你应该判断fgets()为NULL,不判断而继续使用buf的内容,自己的程序是不对的。

foef(stream)针对的是”流“, 用一个indicator(指示)表明文件尾,而feof判断这个指示是否设置,而不是判断当前SEEK数值是否 ...


一直很欣赏  思一克, 不会放过任何一个细小的细节。
见你说了这么多,忍不住顺便也说一下,对于pipe,sock,本身是不可seek的,这是其一;
另外,如果当前的pipe/sock里没有可读的数据,fgets会一直等待,根本不会返回:),因此
也不会给判断buf的机会:) 除非pipe/sock另外一写入端close或者读到足够的字节,或者被信号打断.
如果你能进入到判定buf的时候,一定是1. 读到足够的字节数,2不足,但是已经到文件尾。
如果buf[0] == 0x00, 那么,一定是到了文件尾:)
考虑到低速设备容易被信号打断,因此,一上来就用了,如果对于磁盘文件 ...

[ 本帖最后由 ivhb 于 2007-7-3 16:58 编辑 ]

论坛徽章:
0
20 [报告]
发表于 2007-07-03 17:02 |只看该作者
可能我用直接用sock, pipe做例子不对。

但可以想,LIB库,用一个指示来判断,应该有其道理的,虽然会引起误导。
根据是什么,就是这么成熟的使用多年的库,有是这么简单的问题,不可能有错误。而且man page中说的也是那样判断eof的指示是否设置,而不是判断目前是否读在最后一个字节。至于指示怎么被设置没有说。

再有,且不说以上的,就是程序中判断错误,也应该用最后那个操作fgets()来判断,否则直接fgets后就利用buf内容是绝对不对的,因为fgets返回错误的情况呢?




原帖由 ivhb 于 2007-7-3 16:48 发表


一直很欣赏  思一克, 不会放过任何一个细小的细节。
见你说了这么多,忍不住顺便也说一下,对于pipe,sock,本身是不可seek的,这是其一;
另外,如果当前的pipe/sock里没有可读的数据,fgets会一直等待, ...
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP