2015-03-13 6 views
0

Я проверил множество ситуаций с getchar() и putchar() и '\n' и EOF (в Visual Studio), чтобы лучше понять, как работает буферизация и getchar.путают с буфером и EOF и getchar

Если мой код

int c; 
printf("Enter character\n"); 
/* 1 - number for explaining steps */ 
c = getchar(); 
putchar(c); 

/* 2 */ 
c = getchar(); 
putchar(c); 

printf("hi"); 

В этом коде, если я вхожу символ a и нажмите Enter, он будет показывать

a 
hi 

Это означает, что, когда я при нажатии ввести '\n' будут сохранены в буфере тоже, а затем первый элемент в буфере (a) переходит к первому c=getchar() и печатается a; то второй элемент в буфере (\n) переходит ко второму c=getchar() и печатает новую строку.

я делаю вывод, что '\n' сохраняется в буфере, и это не является результат способности командования идти на новую строку при нажатии войти, потому что я тестировал другой код для этого:

while ((c = getchar()) != '\n') 
    putchar(c); 
printf("hi"); 

В этом коде, когда Я напечатал a и нажмите клавишу ВВОД печатает ahi и новая линия не печатает это означает, что, когда a передается getchar(), putchar() печатает тогда, когда getchar() получает '\n', цикл завершается и putchar() внутри цикла не печатает новую строку поэтому команда не является причиной для n ew.

Теперь я хочу, чтобы проверить другой код:

int c; 
    while ((c = getchar()) != EOF) 
    putchar(c); 
    printf("hi"); 
    return 0; 

В одном случае я прохожу его abc и сигнал EOF (в моей системе^Z (Ctrl + Z)) он будет показывать abc-> , Если мы посмотрим на него, как и предыдущий код: abc-1(or every thing else shows eof)'\n' должны были сохранены в буфере и первый a перейти к первому GetChar (работам цикла первого раза!) b пассов на второй GetChar затем c переходит к третьим —, а затем -1 должен были отправлены в c=getchar() , и это противоречит условию, и цикл должен завершиться.

Однако он печатает -> и цикл продолжается, а новая строка (последний элемент в буфере) не печатает. Вместо этого, когда я просто ctr +z, когда c=getchar() считывает знак EOF из буфера, оканчивается контур и печатается новая строка, так почему он печатает новую строку? Он читает EOF, и в этой ситуации он не должен читать ничего в буфере .

+0

Этот последний абзац - почти полностью одно предложение/вопрос; можете ли вы переформатировать его? –

+0

В будущих вопросах и обходе кода в целом вы можете поместить такие вещи, как шаг № 1 в комментариях к коду. Программисты будут знать, чтобы посмотреть в комментариях, когда вы говорите о шаге 1, и это позволяет нашим внутренним компиляторам C отбрасывать свои приемы, когда мы читаем ваш код. – Philip

+0

В последнем примере после обработки c следующий символ - '-' не '-1'. Вы уверены, что «>» не является вашим приглашением в терминале? – Philip

ответ

1

Ваш план того, как ввод сначала начинается a, а затем в первом примере строка новой строки в основном правильная. Newline - совершенно нормальный характер, поскольку это касается getchar(); действительно, нет ненормальных персонажей. getchar() может вернуть любое 8-битное значение, которое соответствует char, плюс одно дополнительное значение, известное как EOF. Вот почему его возвращаемое значение должно быть сохранено в int, как и было сделано правильно.

Стандартные функции ввода-вывода возвращают EOF, когда базовые read() системные вызовы возвращают 0 байтов, доступных для чтения — или при возникновении ошибки.

При вводе abcControl-Z на Windows, (нужно ввести Control-D вместо этого на Unix), то:

  1. Терминал водитель делает символы в данный момент в буфере (abc), доступный для системного вызова read().
  2. Системный вызов read() заполняет стандартный буфер ввода-вывода этими символами.
  3. Последовательные getchar() звонки возвращаются a, b и c.
  4. Следующий getchar() ждет большего количества ввода.

Это не EOF; это просто сбрасывало символы на линии в программу. Чтобы получить эффект EOF, вам нужно будет ввести Control-Z дважды в строке после abc. Первый сбросит abc; второй будет генерировать read() из 0 байтов, указывая EOF.

Драйвер терминала также делает ввод доступным при нажатии кнопки новой строки (Enter). Если вы наберете Control-Z сразу после ввода Enter, все ноль ожидающих ввода символов отправляются с терминала в программу, поэтому read() возвращает 0, поэтому стандартный пакет ввода-вывода сообщает EOF.

Обратите внимание, что до тех пор, пока вы не нажмете ввод или указатель EOF, вы можете редактировать данные в строке с помощью обратного пространства и других параметров редактирования, включая удаление всех данных. Как только вы нажмете enter или EOF-индикацию, вы больше не сможете редактировать данные, которые были доступны для read().

Аналогичное поведение наблюдается в Unix; вы дважды вводите индикацию EOF для завершения ввода средней линии; один раз для завершения ввода в начале строки.

Есть много связанных вопросов на переполнение стека, в том числе таких:

+0

Еще один хорошо представленный ответ! – chux

+0

nice answer.but я спрашивал о окнах, что мы должны нажать enter после^c и нажать первый раз, не смывая буфер, который я тестировал в linux, было очевидно, как это работает, но в окнах я не знаю, почему он печатает (' -> ') и почему он не печатает новую строку, и почему, если бы я нажал^c, нажмите клавишу ввода без каких-либо других символов, она печатает новую строку после завершения цикла, который я ожидал, чтобы не читать остальную часть буфера. – HabibKazemi

+0

Я не мог отредактировать последнее изменение комментария^c с^z извините. и я должен упомянуть, что он печатает «->» при наборе текста «abc^z» нажимаем enter. – HabibKazemi

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