2016-12-18 4 views
2

Я работал над следующим примером кода C от Deitel & Deitel. Кажется, что код должен печатать символы, введенные до EOF, в обратном порядке. Но я должен нажать EOF (ctrl + z в окнах) несколько раз и ввести клавишу, чтобы сделать это. Не могли бы вы сообщить мне, почему он не отвечает на первый EOF?getchar и EOF

#include <stdio.h> 

int main(void) 
{ 
    int c; 
    if ((c = getchar()) != EOF) { 
     main(); 
     printf("%c", c); 
    } /* end if */ 

    return 0; 
} 
+7

Этот код не очень хороший пример. Вы должны * никогда * не вызывать 'main' рекурсивно. –

+2

А что означает «scanf» (упомянутый в названии), связанный с этим вопросом? –

+0

'Ctrl-Z' должна быть первая запись или первая запись после' новой строки'. При использовании 'scanf' ключевую комбинацию« Ctrl-Z »нужно нажать три раза, я все еще не понимаю, почему. –

ответ

0

Это связано с тем, что консоль Windows передает CTRL + Z в программу. Вероятно, вы ожидаете, что вы составите строку и не узнаете строку до тех пор, пока в ней не будет символ CTRL-Z. Поэтому он ждет, пока вы случайно не нажмете пробел и не войдете.

Просто эхо все в программе с нуля, чтобы точно увидеть, что происходит.

0

Ну getchar(3) это функция, которая работает в буферном режиме, так что вы должны ввести некоторые символы и нажмите символ, используемый для сигнала конца данных (^ D в Unix,^Z в окнах)

Рассматривается задача вот то, что драйвер консоли Windows не указан так же, как драйвер unix tty, поэтому поведение будет, в общем, не совпадать ... Попробуйте протестировать программу в реальной среде unix (или linux) и посмотрите, вход, по крайней мере, обратный, как показано в примере.

В режиме unix поведение ввода терминала заключается в том, что ^D интерпретируется сразу же после его нажатия, но если какой-либо вход находится в буфере драйвера до него, он сделает эти входные данные доступными для программы (так что вы будете придется нажать на него второй раз, чтобы сигнализировать состояние EOF, которое состоит из read(2), результатом которого является 0 символов, которые действительно читаются). В случае, если вы нажали <Return> до ^D (возврат делает все данные доступными для приложения, с той разницей, что к чтению данных также добавляется символ \n), входной буфер пуст, поэтому условие EOF происходит сразу после <return> голец.

В окнах вам нужно нажать <return> на все, что нужно читать (^Z, чтобы быть интерпретированным), и все усложняется.

Кстати, я выполнил свою программу на системе BSD Unix, со следующим результатом:

$ a.out 
apsiodjfpaosijdfa 
^D 
afdjisoapfjdoispa$ _ 

Объяснение: первая строка строка ввода «apsiodjfpaosijdfa», а затем \n, и ^D сигнализация конец ввода. Все эти данные сразу поступают в приложение, а getchar() затем обрабатывает его по символу. Он сначала печатает \n (делая строку ниже ^D), а затем входные символы, обратные. Поскольку в начале данных не было \r, в конце возврата не возвращается, а подсказки появляются рядом с выходом. Финал _ сигнализирует положение курсора в конце.

Если вы не хотите иметь дело с символами конца символов (или не имеете никакого unix под рукой для проведения теста), вы можете использовать текстовый файл для проверки своей программы (нет eof char, только фактический конец файла), перенаправляя программный ввод из файла, как в этом примере, который использует исходный код как входной:

$ a.out <pru.c 

} 
;0 nruter  

/* fi dne */ }  
;) c ,"c%" (ftnirp   
;)(niam   
{) FOE =!))(rahcteg = c ((fi  
;c tni  
{ 
) diov (niam tni 

>h.oidts< edulcni#$ _ 
Смежные вопросы