【问题标题】:Why does this program behave like `tail -f`为什么这个程序表现得像`tail -f`
【发布时间】:2013-07-26 12:57:53
【问题描述】:
int main(int argc, char *argv[])
{
    int c = EOF;
    FILE *fp = fopen("./temp.txt", "r");
    assert(fp!=NULL);
    while (1) {
        c = fgetc(fp);
        if (EOF != c) {
            putchar(c);
        }
    }

    return 0;
}

temp.txt 是一个缓慢增加的日志文件,所以这个程序可以读取 EOF。在它第一次遇到 EOF 之后,我认为它应该停止获取 temp.txt 的新添加数据,而它就像 tail -f temp.txt 并继续打印文件的新行。

是的,我知道有一个无限循环。问题是我想, 当 fgetc 第一次遇到 EOF 时,它应该在结构 fp 中做一些记录, fgetc 的下一次调用应该检查这一点并立即返回 EOF。 为什么它继续读取磁盘上的数据,它没有到达文件末尾? 这是预期的行为吗?

【问题讨论】:

  • 最好写:while ((c = fgetc(fp)) != EFO){ putchar(c);}
  • 您显然是在将您的程序与 Glibc 链接起来。如果你将它与 uClibc 链接起来,它会在 EOF 之后第一次调用 fgetc 时崩溃。在未指定 EOF 之后从 FILE 中读取。
  • 请注意,知道您在文件末尾的正确方法是使用手册页中描述的 feof 函数。
  • 许多实现都如您所愿。但是,并非所有人都这样做。 fgetc 在为流返回 EOF 后的行为是未指定的。

标签: c file eof fgetc


【解决方案1】:

快速回答是,没有退出while 循环的break

当它读取EOF 时,它会循环返回并保持c = fgetc(fp);

如果您需要它在到达 EOF 时停止阅读,您可以添加 else:

while (1) {
    c = fgetc(fp);
    if (EOF != c) {
        putchar(c);
    } else {
        // reached the EOF
        break;
    }
}

【讨论】:

    【解决方案2】:

    你并没有告诉它在找到 EOF 时离开 while 循环,你只是说如果你确实找到了 EOF,就不要对它做任何事情。您需要从循环中放置一个条件中断,或者有一个条件,直到 while 循环将继续。

    【讨论】:

      【解决方案3】:
      int main(int argc, char *argv[])
      {
          int c = EOF;
          FILE *fp = fopen("./temp.txt", "r");
          assert(fp!=NULL);
          while (1) { // here
              c = fgetc(fp);
              if (EOF != c) {
                  putchar(c);
              }
          }
      
          return 0;
      }
      

      这是因为您有一个无法停止的无限循环(某些信号除外)。该程序将永远读取temp.txt

      【讨论】:

        【解决方案4】:
        int main(int argc, char *argv[])
        {
            int c = EOF;
            FILE *fp = fopen("./temp.txt", "r");
            assert(fp!=NULL);
            while (1) {
                c = fgetc(fp);
                if (EOF != c) {
                    putchar(c);
                }
                else
                  break; //this will fix your problem of infinite loop even finding EOF
            }
        
            return 0;
        }
        

        【讨论】:

          【解决方案5】:

          IMO 这样做会更好看

          int c = 0;
          while ((c = fgetc(fp)) != EOF)
          {
              putchar(c);
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-10-28
            • 2011-08-31
            • 2011-08-06
            • 2023-01-07
            相关资源
            最近更新 更多