免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
31 [报告]
发表于 2007-07-04 11:04 |只看该作者
原帖由 ivhb 于 2007-7-4 10:26 发表



假定进程A读取文件已经到了文件尾,feof测试为真。
如果此时进程B追加A正在读取的文件,你觉得,如果A不发生进一步的读/写动作,
接着测试feof,你觉得是真还是假?

feof仅仅是个宏,仅仅读取了上次 ...

我的理解是:fgets读到文件最后一行的时候(返回不是NULL) ,feof测试为假,再fgets一次(返回为NULL),再feof测试为真。对否?
你的问题我觉得是 如果在A中用feof是真,在B中用feof是假,对否?

论坛徽章:
0
32 [报告]
发表于 2007-07-04 11:06 |只看该作者
原帖由 福瑞哈哥 于 2007-7-4 11:04 发表
难道还有其他选择?
fgets返回null表示这个文件对程序来说是读完了。基本上就是这样,有其他情况99%你也不会处理的。


我的意思是fgets出错的情况有可能么?这时候fgets是什么反应?好奇

论坛徽章:
0
33 [报告]
发表于 2007-07-04 11:08 |只看该作者
看man page,

gets() and fgets() return s on success, and NULL on error or when  end
       of file occurs while no characters have been read.

不要将问题考虑的那样复杂


理论上fgets确实有出错的可能,但是谁又会去处理它呢,又如何处理呢?至今阅码无数,尚无见识过处理fgets错误的代码。

原帖由 while(1) 于 2007-7-4 11:06 发表

我的意思是fgets出错的情况有可能么?这时候fgets是什么反应?好奇

[ 本帖最后由 思一克 于 2007-7-5 15:20 编辑 ]

论坛徽章:
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
34 [报告]
发表于 2007-07-04 11:42 |只看该作者
原帖由 福瑞哈哥 于 2007-7-4 11:08 发表
理论上fgets确实有出错的可能,但是谁又会去处理它呢,又如何处理呢?至今阅码无数,尚无见识过处理fgets错误的代码。


不会这么夸张吧?

  1. while(fgets(..., stream)){
  2.         /* ... */
  3. }

  4. if(ferror(stream)){
  5.         /* ... */
  6. }
复制代码

这种例子一堆一堆的。

[ 本帖最后由 MMMIX 于 2007-7-4 11:44 编辑 ]

论坛徽章:
0
35 [报告]
发表于 2007-07-05 11:31 |只看该作者
每次读之前memset一下buffer

论坛徽章:
0
36 [报告]
发表于 2007-07-05 11:32 |只看该作者
原帖由 MMMIX 于 2007-7-4 11:42 发表

不会这么夸张吧?

while(fgets(..., stream)){
        /* ... */
}

if(ferror(stream)){
        /* ... */
}

这种例子一堆一堆的。


我是没见过。 if(ferror(stream)) {}里面写什么?

论坛徽章:
0
37 [报告]
发表于 2007-07-05 11:46 |只看该作者
不如用C++的ifstream + while循环

ifstream in("/tmp/test.txt",ios::in);
string temp;

while(getline(in,temp,'\n'))  
{
    //.....
}

论坛徽章:
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
38 [报告]
发表于 2007-07-05 12:24 |只看该作者
原帖由 福瑞哈哥 于 2007-7-5 11:32 发表


我是没见过。 if(ferror(stream)) {}里面写什么?

来个完整的例子吧,APUE2 的 Figure 15.11

  1. #include "apue.h"
  2. #include <sys/wait.h>

  3. #define PAGER   "${PAGER:-more}" /* environment variable, or default */

  4. int
  5. main(int argc, char *argv[])
  6. {
  7.         char    line[MAXLINE];
  8.         FILE    *fpin, *fpout;

  9.         if (argc != 2)
  10.                 err_quit("usage: a.out <pathname>");
  11.         if ((fpin = fopen(argv[1], "r")) == NULL)
  12.                 err_sys("can't open %s", argv[1]);

  13.         if ((fpout = popen(PAGER, "w")) == NULL)
  14.                 err_sys("popen error");

  15.         /* copy argv[1] to pager */
  16.         while (fgets(line, MAXLINE, fpin) != NULL) {
  17.                 if (fputs(line, fpout) == EOF)
  18.                         err_sys("fputs error to pipe");
  19.         }
  20.         if (ferror(fpin))
  21.                 err_sys("fgets error");
  22.         if (pclose(fpout) == -1)
  23.                 err_sys("pclose error");

  24.         exit(0);
  25. }
复制代码

论坛徽章:
0
39 [报告]
发表于 2007-07-05 14:27 |只看该作者
如果要提供一个函数给其他人用,ferror判断就有用了吧。
比如读取informix下unload出来的文件,如果行尾是\表示连接下一行。
如果提供一个函数叫做

  1. static FILE *fp;

  2. static int
  3. init_file_read(char *filenmame)
  4. {
  5.   fp = fopen(filename, "r");
  6. }

  7. int
  8. has_next_line(register char *s, char spec)
  9. {
  10.   char  c, tr = 0;

  11.   if (s[0] == 0x00)
  12.     return (0);

  13.   while (c = *s ++) {
  14.     if (tr == 1
  15.          && s[0] == 0x00
  16.          && c == '\n')
  17.       return (1);

  18.     if (c != spec)
  19.       tr = 0;
  20.     else
  21.       tr = 1 - tr;
  22.   }

  23.   return (0);
  24. }

  25. int
  26. get_consecutive_lines(char *s, int len)
  27. {
  28.   static char spec = '\\';
  29.   int lines = 0;
  30.   int cur_line_len = 0;

  31.   if (fp == NULL)
  32.     return (-1);

  33.   /* s remains unchanged */
  34.   if (len < 2)
  35.     return (0);

  36.   do {
  37.     s += cur_line_len;
  38.     len -= cur_line_len;

  39.     if (len < 2)
  40.       break;

  41.     if (fgets(s, len, fp) == NULL)
  42.       break;

  43.     cur_line_len = strlen(s);

  44.     if (s[0] != 0x00
  45.          && s[cur_line_len-1] == '\n')
  46.       lines ++;
  47.   } while (has_next_line(s, spec));

  48.   if (ferror(fp))
  49.     return (-1);

  50.   return (lines);
  51. }

复制代码


这样可以约定返回<0就是出错,>= 0 就是实际读取的行数,表示成功。
调用你函数的人就可以根据返回来决定采取什么动作了。
.....
我们不讨论这么封装模块化的优劣,仅仅是个例子来说明一下而已。

[ 本帖最后由 ivhb 于 2007-7-5 14:30 编辑 ]

论坛徽章:
0
40 [报告]
发表于 2007-07-05 15:22 |只看该作者
gets() and fgets() return s on success, and NULL on error or when  end
       of file occurs while no characters have been read.

fgets错误或EOF都返回NULL
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP