2011-12-14 13 views
5

Этот код исходит из K & R. Я читал его несколько раз, но мне все еще кажется, что я не понимаю.Просьба пояснить этот пример C Код

#define BUFSIZE 100 

char buf[BUFSIZE]; 
int bufp = 0; 

int getch(void) 
{ 
     return(bufp>0)?buf[--bufp]:getchar(); 
} 

int ungetch(int c) 
{ 
     if(bufp>=BUFSIZE) 
      printf("too many characters"); 
     else buf[bufp++]=c; 
} 

Цель этих двух функций, поэтому K & говорит R, чтобы предотвратить программу от чтения слишком много входных данных. то есть без этого кода функция, возможно, не сможет определить, что она достаточно читала данные без предварительного чтения. Но я не понимаю, как это работает.

Например, рассмотрим getch(). Насколько я могу видеть, что это шаги он принимает:

  1. проверить, если bufp больше 0.
  2. если да, то возвращают значение полукокса из Buf [- bufp].
  3. возвращение назад getchar().

Я хотел бы задать более конкретный вопрос, но я в буквальном смысле не знаю, как этот код достигает того, что он предназначен для достижения, поэтому мой вопрос: что такое (а) цель и (б) аргументация этого кода?

Заранее благодарен.

ПРИМЕЧАНИЕ: Для всех вентиляторов K & R, этот код можно найти на странице 79 (в зависимости от издания, я полагаю)

+0

Тест внутри 'ungetch' должен, вероятно, включать' bufp' not 'printf' в его состояние. Наверное, это опечатка. –

+0

У меня сейчас нет K & R, но я думаю, что в ungetch условие if должно быть 'bufp> = BUFSIZE' – kol

+0

Извините, вероятно, моя ошибка. SOmeone исправил это сейчас, поэтому я не могу вспомнить, что я набрал в оригинале. –

ответ

9

(а) Цель этого кода, чтобы иметь возможность читать характер а затем «не читайте» его, если окажется, что вы случайно прочитали символ слишком много (с максимальным количеством 100 символов «не читайте»). Это полезно для парсеров с lookahead.

(b) getch читает с buf, если у него есть содержимое, указанное bufp>0. Если buf пуст, он вызывает getchar. Обратите внимание, что он использует buf как стек: он читает его справа налево.

ungetch толкает персонажа в стек buf после выполнения проверки, чтобы убедиться, что стек не заполнен.

+0

Но предполагая, что ungetch isnt не вызван, тогда getch всегда будет возвращать getchar(), так как bufp будет равен нулю бесконечно. Я не понимаю эту часть. –

+0

@JJG: Правильно, если вы никогда не называете 'ungetch', тогда вам не понадобится буфер и всегда будет получать свежий ввод от' getchar'. –

1

Код на самом деле не предназначен для «слишком большого ввода», а это значит, что вы можете положить символы уже прочитанные.

Например, вы читаете один символ с getch, смотрите, если это письмо, верните его с помощью ungetch и прочитайте все буквы в цикле. Это способ предсказать, каким будет следующий персонаж.

1

Этот блок кода предназначен для использования программами, которые принимают решения на основе того, что они читают из потока. Иногда такие программы должны смотреть на несколько символов из потока, фактически не потребляя входные данные. Например, если ваш ввод выглядит как abcde12xy789, и вы должны разбить его на abcde, 12, xy, 789 (т. Е. Отдельные группы последовательных букв из групп последовательных цифр), вы не знаете, что вы достигли конца группы букв пока не увидите цифру. Однако вы не хотите потреблять эту цифру в то время, когда вы ее видите: все, что вам нужно, это знать, что группа букв заканчивается; вам нужен способ «вернуть» эту цифру.В этой ситуации полезно использовать ungetch: после того, как вы увидите цифру после группы букв, вы вернете цифру, позвонив по номеру ungetch. Ваша следующая итерация выберет эту цифру с помощью того же механизма getch, избавив вас от необходимости сохранять характер, который вы читаете, но не потребляете.

0
    1. Другая идея, также показанная здесь, также может быть названа как очень примитивная система управления стеками ввода-вывода и дает реализацию функции getch() и ungetch().
    2. Чтобы сделать шаг вперед, предположим, что вы хотите создать операционную систему, как вы можете обрабатывать память, в которой хранятся все нажатия клавиш?

Это решается вышеуказанным фрагментом кода. Расширение этой концепции используется при обработке файлов, особенно при редактировании файлов. В этом случае вместо использования getchar(), который используется для ввода ввода со стандартного ввода, файл используется как источник ввода.

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