2015-02-16 3 views
0

У меня есть следующие программы:перенаправление вывода команды оболочки для программы C

/* a.c */ 
#include <stdio.h> 

int 
main(int argc, char* argv[]){  

size_t size=0;  
char* lineptr;  

    while(getline(&lineptr, &size, stdin)){   
     fprintf(stderr, "line = %s\n", lineptr);  
     if(lineptr){  
      free(lineptr);  
      lineptr = NULL;  
     }  
    }  

return 0;  
}  

Я перенаправил вывод оболочки команды «LS» в эту программу, используя
следующей строки:

ls | ./a.out 

Ожидаемый результат:
программа должна распечатать имя всех файлов в текущем каталоге
и прекратить работу.

Фактический выход:
Программа выводит имена всех файлов, но не прекращается,
вместо этого петля бесконечно и печатает последнюю запись бесконечно.

Благодаря

+2

Вы прочитали инструкцию для 'getline'? –

+0

Я игнорировал возвращаемое значение getline. в конце он возвращает -1, который оказывается истинным значением, таким образом, бесконечным циклом. –

+0

Поскольку вы не используете аргументы, вам лучше будет быть явным и написать 'int main (void)'. –

ответ

4

getline функция GNU возвращает -1 на конец из файла (или ошибки). Используйте

while(-1 != getline(&lineptr, &size, stdin)) 

... и установите lineptr в NULL перед первым вызовом getline.

Кроме того, у вас не должно быть free указатель на каждой итерации цикла; вы можете использовать предыдущий указатель и free один раз в конце:

size_t size = 0; 
char* lineptr = NULL; 

while(-1 != getline(&lineptr, &size, stdin)){ 
    fprintf(stderr, "line = %s", lineptr); 
} 

free(lineptr); 

getline будет использовать realloc внутренне по мере необходимости. Обратите внимание, что вы должны убедиться, что lineptr и size не изменены между вызовами getline, чтобы это работало (хотя вы можете изменить строку, на которую lineptr баллов).

+0

Я прочитал руководство, он говорит, что если lineptr равно NULL, тогда значение размера игнорируется, поэтому я сделал lineptr равным NULL после каждой итерации –

+1

Это работает, но это неэффективно. Нет необходимости делать выделение кучи на каждой итерации только тогда, когда выделенное пространство слишком мало и должно быть увеличено. 'getline' обрабатывает это внутренне, поэтому нет необходимости не использовать его. – Wintermute

Смежные вопросы