2015-08-16 2 views
1

Немного фона, я пишу программу, которая играет в игру «Ящики», она запускается в командной строке linux и написана на C. Там есть приглашение, ожидающее ввода пользователя а затем считывается с помощью fgets() и интерпретируется и т. д.Обнаружение EOF с помощью fgets(), где filesteam is stdin

Как часть спецификации задачи, я должен возвратить определенную ошибку, если достигню «Конец файла в ожидании ввода пользователя». Я понимаю, что fgets() возвращает нуль, когда она достигает EOF ... но у меня есть

fgets(input,max_buffer,stdin);

безотлагательным цикла, если пользователь выходит преждевременно говорить с CTRL + C или CTRL + D это значит, что input == NULL?

Могу ли я определить, когда пользователь делает это с помощью fgets?

Просто пытаясь остричь голову, заранее за помощь.

(OS: UNIX) (Компилятор: GCC - C90)

+0

Ctl-C убивает программу, поэтому 'fgets' никогда не возвращается. Ctl-D вызывает конец состояния файла. 'man fgets' –

ответ

2

От here, fgets:

читает символы из потока и сохраняет их в виде строки C в ул до (Num-1) символы были считаны или либо перевод строки или конец файла-это достигнуто, в зависимости от того, что произойдет раньше.

Символ новой строки заставляет fgets останавливать чтение, но считается действительным символом функции и входит в строку, скопированную на str.

Конечный символ нуль автоматически добавляется после символов, скопированных на str.

Так, fgets вернется, когда пользователь вводит CTRL-D (EOF) или, когда \n (символ новой строки) встречается. CTRL-C будет по умолчанию полностью завершает вашу программу.

Если вы хотите, чтобы поймать CTRL-C, и выйти изящно, вы можете:

#include <signal.h> 

void intHandler(int dummy) { 
    //graceful CTRL-C exit code. 
} 

int main(void) { 
    signal(SIGINT, intHandler); 
    //your code 
} 
+1

Технически, это ошибка, чтобы сказать, что Control-C завершает вашу программу. Он * может *, но это только поведение по умолчанию и может быть изменено, как вы демонстрируете. SIGTERM и SIGKILL специально разработаны для того, чтобы убить процесс, поскольку SIGKILL почти гарантированно работает, поскольку он не может быть заблокирован или проигнорирован. – SevenBits

+0

@SevenBits, спасибо за ваш ответ на мой недосмотр. Мой ответ был обновлен, чтобы отразить вашу точку зрения. – MeetTitan

1

Когда конечный пользователь завершает работу на постоянной основе с помощью Ctrl + C, ваша программа теряет контроль сразу, а это означает, что вы не получите каких-либо дополнительных материалов из fgets, даже NULL.

С другой стороны, Ctrl + D закрывает входной поток без закрытия вашей программы, поэтому вы получите результат NULL от вызова fgets.

Вы можете настроить программу для обработки Ctrl + C обработкой сигнала, но такая обработка будет происходить вне входного цикла.

+0

У меня создалось впечатление, что при возникновении ошибки возвращается нулевой указатель или не будет считаться ошибкой control-c. –

+1

@ l'L'l Ctrl + C не является ошибкой ввода-вывода, он обрабатывается как связанный сигнал, чтобы закрыть процесс. – dasblinkenlight

+0

А, ладно ... Я должен был иметь воспоминания о днях Ascii [ETX] (https://en.wikipedia.org/wiki/End-of-text_character)! :) –

2

документация (C99 §7.19.7.2):

Функция fgets возвращает s если успешный. Если конец файла встречается и в массив не считываются символы, содержимое массива остается неизменным и возвращается нулевой указатель. Если во время операции возникает ошибка чтения, содержимое массива является неопределенным и возвращается нулевой указатель.

Так что, если конец файла-происходит, но символы были считаны, fgets не вернется NULL. Если EOF происходит до считывания любого ввода, он вернет NULL.

Вы можете различать EOF и ошибку чтения с помощью функций feof и ferror.