2013-09-08 3 views
1
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define BUF_SIZE 1024 

int main() 
{ 
    char buffer[BUF_SIZE]; 
    int contentSize = 1; 

    char* content = (char*)malloc(sizeof(char) * BUF_SIZE); 
    content[0] = '\0'; 

    while(fgets(buffer, BUF_SIZE, stdin)) 
    { 
     contentSize = contentSize + strlen(buffer); 
     content = (char*)realloc(content, contentSize); 
     strcat(content, buffer); 
    } 

    return 0; 
} 

im пытается прочитать во всем, введенном пользователем (даже пробельные символы), и я довольно близок к тому, чтобы заставить его работать, но цикл никогда не заканчивается. fgets() просто продолжает просить больше ввода, как мне это исправить.Почему цикл fgets() никогда не заканчивается?

+0

Как вы сказали в комментарии ниже, вы используете Windows (эта информация стоит поставить в вопрос :-). - Вы попробовали клавишу «F6» для EOF? Сравните http://stackoverflow.com/questions/10589637/having-troubles-with-eof-on-windows-7. –

+0

да, что сработало! интересно, спасибо – user2756746

+0

Возможный дубликат [Проблемы с EOF в Windows 7] (http://stackoverflow.com/questions/10589637/having-troubles-with-eof-on-windows-7) –

ответ

3

возвращает указатель на буфер (который не является указателем NULL), который вы передали ему, пока он не сможет прочитать больше строк из файла.

Конечно, если вы читаете со стандартного ввода, он всегда будет ждать другую строку, поэтому вы должны указать явно отправить EOF на терминал, чтобы он сообщал о конце файла. Вы можете сделать это, нажав, например, <ctrl> + <D>.

+3

+ в большинстве * nixes, которые я видел; + в Windows. – cHao

+0

Я просто попробовал это, я положил [Control] + D в конце некоторых случайных символов, и он по-прежнему запрашивает больше ввода. im используя окна 8. ctrl + z также не работает. – user2756746

+2

@ user2756746: Возможно, вам придется убедиться, что это на линии само по себе. – cHao

0

Один из способов заключается в том, чтобы пользователь вводил определенное ключевое слово (например, quit или quit()), а затем выходил из цикла while.

while(fgets(buffer, BUF_SIZE, stdin)) { 
      contentSize = contentSize + strlen(buffer); 
      content = (char*)realloc(content, contentSize); 
      strcat(content, buffer); 
      if (strncmp(buffer, "quit", strlen("quit")) == 0) { 
       break; 
      } 
} 
+1

Для программы, которая ожидает работать в интерактивном режиме (то есть: ожидает, что stdin будет терминалом), это немного менее уродливое (после того, как объект «quit-in-the-buffer» исправлен), чем требуется, чтобы пользователь вводил символ EOF , Можно легко представить себе ситуацию, когда вы хотите, чтобы у вас была строка с надписью «quit». Вам нужно будет предоставить какой-то способ сделать это. – cHao

+0

Выход из буфера может быть исправлен путем выполнения сравнения перед повторным использованием и копированием. – cHao

+0

это сложнее, чем я себе представлял. что, если я просто использую цикл for? будет работать – user2756746

0

Петля никогда не заканчивается, потому что OP не закрывается stdin. Как только stdin будет закрыт и все данные будут прочитаны, fgets() вернет NULL.

Решение проблемы с H2CO3 находится на прицеле, но OP, возможно, пропустил некоторые тонкости окон.

A <Ctrl>+<Z> будет сигнализировать EOF, если входной буфер пуст, и за ним следует Enter. Пример A, B, C, Enter, пустой буфер, <Ctrl>+<Z>, Enter.

Если у входного буфера все готовые данные есть данные, то <Ctrl>+<Z> читается как <Ctrl>+<Z> (ASCII 26).

Идея «бросить», имеет смысл, но пользователь все еще может ввести <Ctrl>+<Z>, Enter. Код должен быть готов к этому. (Опубликованный ответ «quit» делает это.) Я предлагаю избегать волшебных слов - если только его «relinquo codicem».

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