Чтение данных со стандартного ввода в C - PullRequest
0 голосов
/ 10 декабря 2010

Я пытаюсь прочитать из 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 ]

1 голос
/ 10 декабря 2010

После того, как FILE * достигло EOF, оно остается в состоянии, когда больше не будет считывать данные, пока вы не очистите бит 'EOF' либо с помощью clearerr(), либо с помощью fseek(). Однако, если стандартный вход подключен к терминалу, это устройство не является доступным для поиска, поэтому вместо очистки ошибки оно может ничего не делать:

POSIX говорит:

Поведение fseek () на устройствах, которые не могут искать, определяется реализацией.

Ваше условие входа в цикл подозрительно; Вы должны спать перед его запуском, и вам нужно спать на каждой итерации. Действительно, обычно вы пишете tail -f, не заботясь о размере файла; Вы спите, попробуйте прочитать до следующего «EOF», сбросьте индикатор файла EOF и повторите. Также обратите внимание, что размер трубы или терминала не определен.


Отдельно принято вызывать аргумент FILE * для функции filename; это имеет совершенно неправильный смысл. Имя файла - это строка.

0 голосов
/ 10 декабря 2010

Это не совсем стандартный C:

size(file);

Вызовите stat () для получения информации о файле - тип организации файла, размер файла и разрешения.

Что ваш код делает, так это в конечном итоге устанавливает указатель файла в конец файла, когда он пытается его прочитать. Вместо этого рассмотрите stat () (или fstat () для открытого файла).

rewind () сбрасывает указатель файла на начало файла, fseek () помещает его в любое место.

tail -f неоднократно пытается файл в точке EOF с коротким перерывом между попытками .... Он не считает EOF ошибкой. Он запоминает текущее смещение файла для EOF, затем fseeks () с помощью SEEK_END, затем вызывает ftell () и сравнивает смещения. Если есть разница, то fseek () возвращается к последней известной конечной точке и считывает данные.

Это описание из старого источника Unix. Я уверен, что с тех пор его подправили.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...