从C中的stdin读取数据

时间:2010-12-10 01:44:50

标签: c stdin

我正在尝试从stdin读取并输出数据,但事情是有效的,除了它没有输出新的传入数据。我不太确定问题出在哪里。我猜测确定stdin大小时有一些事情要做。任何帮助将不胜感激!感谢

tail -f file | my_prog

更新

#include <stdio.h>
#include <sys/stat.h>

long size(FILE *st_in) {
    struct stat st;
    if (fstat(fileno(st_in), &st) == 0)
        return st.st_size;
    return -1;
}

int main (){
   FILE *file = stdin;
   char line [ 128 ];  

   while ( fgets ( line, sizeof line, file ) != NULL )
      fputs ( line, stdout ); /* write the line */

   long s1, s2; 
   s1 = size(file);
   for (;;) {
      s2 = size (file);
      if (s2 != s1) {
         if (!fseek (file, s1, SEEK_SET)) {
            while ( fgets ( line, sizeof line, file ) != NULL ) { 
               fputs ( line, stdout ); /* write the line */
            }   
         }   
         s1 = s2; 
         usleep(300000);
      }   
   }   
   return 0;
}

修改:已修复!

2 个答案:

答案 0 :(得分:1)

FILE *达到EOF后,它会保持在不再读取数据的状态,直到您使用clearerr()fseek()清除'EOF'位。但是,如果标准输入连接到终端,那么这不是可搜索设备,因此它不会清除错误,它可能没有做任何有用的事情:

POSIX说:

  

fseek()在无法寻找的设备上的行为是实现定义的。

您的循环输入条件是可疑的;你需要在开始之前睡觉,并且你需要在每次迭代时睡觉。实际上,通常你写tail -f而不用担心文件大小;你睡觉,尝试阅读直到下一个'EOF',重置文件EOF指示器,然后重复。另请注意,未定义管道或终端的大小。


另外,为函数FILE *调用filename参数是常规的;它有完全错误的含义。文件名是一个字符串。

答案 1 :(得分:0)

这不是真正的标准C:

size(file);

调用stat()获取文件信息 - 文件的组织类型,文件大小和权限。

你的代码所做的是最终将文件指针设置为文件的末尾,因为它试图通读它。考虑使用stat()(或打开文件上的fstat())。

rewind()将文件指针重置为文件的开头,fseek()会将它放在你需要的任何地方。

tail -f在EOF点重复尝试文件,在两次尝试之间短暂睡眠....它不会“认为”EOF是一个错误。它会记住EOF的当前文件偏移量,然后使用SEEK_END调用fseeks(),然后调用ftell(),并比较偏移量。如果存在差异,则将fseek() - s返回到最后一个已知端点并读取数据。

此描述来自旧的unix源。我确信从那以后它已经被调整过了。