Язык С




Область действия - часть 3


} ELSE { /* IT'S TOO BIG; SKIP REST OF LINE */ WHILE (C != '\N' && C != EOF) C = GETCHAR(); S[LIM-1] = '\0'; RETURN (TOOBIG); } }

Что же представляют из себя функции 'GETCH' и 'UNGETCH'? Часто так бывает, что программа, считывающая входные данные, не может определить, что она прочла уже достаточно, пока она не прочтет слишком много. Одним из примеров является выбор символов, составляющих число: пока не появится символ, от- личный от цифры, число не закончено. Но при этом программа считывает один лишний символ, символ, для которого она еще не подготовлена. Эта проблема была бы решена, если бы было бы возможно "прочесть обратно" нежелательный символ. Тогда каждый раз, прочитав лишний символ, программа могла бы поместить его об- ратно в файл ввода таким образом, что остальная часть прог- раммы могла бы вести себя так, словно этот символ никогда не считывался. к счастью, такое неполучение символа легко имми- тировать, написав пару действующих совместно функций. Функ- ция GETCH доставляет следующий символ ввода, подлежащий рас- смотрению; функция UNGETCH помещает символ назад во ввод, так что при следующем обращении к GETCH он будет возвращен. То, как эти функции совместно работают, весьма просто. Функция UNGETCH помещает возвращаемые назад символы в сов- местно используемый буфер, являющийся символьным массивом. Функция GETCH читает из этого буфера, если в нем что-либо имеется; если же буфер пуст, она обращается к GETCHAR. При этом также нужна индексирующая переменная, которая будет фиксировать позицию текущего символа в буфере. Так как буфер и его индекс совместно используются функ- циями GETCH и UNGETCH и должны сохранять свои значения в пе- риод между обращениями, они должны быть внешними для обеих функций. Таким образом, мы можем написать GETCH, UNGETCH и эти переменные как:

#DEFINE BUFSIZE 100 CHAR BUF[BUFSIZE]; /* BUFFER FOR UNGETCH */ INT BUFP = 0; /* NEXT FREE POSITION IN BUF */

GETCH() /* GET A (POSSIBLY PUSHED BACK) CHARACTER */ { RETURN((BUFP > 0) ? BUF[--BUFP] : GETCHAR()); }

UNGETCH(C) /* PUSH CHARACTER BACK ON INPUT */ INT C; { IF (BUFP > BUFSIZE) PRINTF("UNGETCH: TOO MANY CHARACTERS\N"); ELSE BUF [BUFP++] = C; }

Мы использовали для хранения возвращаемых символов массив, а не отдельный символ, потому что такая общность может приго- диться в дальнейшем.

Упражнение 4-4

---------------- Напишите функцию UNGETS(S) , которая будет возвращать во ввод целую строку. Должна ли UNGETS иметь дело с BUF и BUFP или она может просто использовать UNGETCH ?

Упражнение 4-5

---------------- Предположите, что может возвращаться только один символ. Из- мените GETCH и UNGETCH соответствующим образом.

Упражнение 4-6

---------------- Наши функции GETCH и UNGETCH не обеспечивают обработку возв- ращенного символа EOF переносимым образом. Решите, каким свойством должны обладать эти функции, если возвращается EOF, и реализуйте ваши выводы.




    Содержание  Назад  Вперед