Опубликован: 15.11.2010 | Уровень: для всех | Доступ: платный
Лекция 5:

Ввод с клавиатуры

< Лекция 4 || Лекция 5: 12 || Лекция 6 >

5.2.2. Консольный ввод в Си

В языке Си и его разновидностях существуют следующие функции для ввода данных с клавиатуры:

  • cgets - чтение строки с консоли;
  • getch - чтение символа с консоли;
  • getche - чтение символа с эхопечатью;
  • kbhit - проверка нажатия клавиши на консоли;
  • cscanf - чтение данных с консоли по формату;
  • getpass - ввод с терминала пароля без эхопечати.

Рассмотрим некоторые из них поподробнее

ФУНКЦИЯ GETCH
ОПИСАНА В: <conio.h> /* Используется только для описания функции */
СИНТАКСИС: int getch() ;
НАЗНАЧЕНИЕ: Ввод одиночного символа с консольного терминала без эхопечати (без вывода на дисплей).
ФУНКЦИЯ ВОЗВРАЩАЕТ: прочитанный символ.
ПРИМЕЧАНИЕ: функция getch использует входной поток stdin.

ФУНКЦИЯ GETCHE
ОПИСАНА В: <conio.h> /* Используется только для описания функции */
СИНТАКСИС: int getche();
НАЗНАЧЕНИЕ: Функция читает одиночный символ с консольного терминала, с эхопечатью введённого символа на экране с текущей позиции курсора.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Прочитанный символ.
ПРИМЕЧАНИЕ:
  1. Нет ошибочных кодов возврата;
  2. Функция корректно обрабатывает "Ctrl+Break".

ФУНКЦИЯ CGETS
ОПИСАНА В: <conio.h> /* Используется только для описания функции */
СИНТАКСИС:
char *cgets(str);
char *str;
НАЗНАЧЕНИЕ: Функция читает строку символов непосредственно с консоли, и помещает строку и её длину по указателю str. Аргумент str должен быть указателем на массив символов;
ЗАМЕЧАНИЕ: Первый элемент массива str[0] должен содержать максимально допустимую длину считываемой строки. Массив должен иметь достаточную длину, чтобы поместить строку, символ ASCII 0 плюс два байта дополнительно для дескриптора;

cgets читает символы до тех пор, пока не прочитаны символы <CR> и <LF>, или пока не будет прочитано установленное число символов. Прочитанная строка начинается со str[2]. Если прочитана комбинация <CR>/<LF>, эти символы будут располагаться за символом конца строки (ASCII 0). Действительная длина строки помещается в str[1] ;

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: указатель на начало строки, то есть на адрес элемента str[2] ;
ПРИМЕЧАНИЕ:
  1. Нет кодов ошибок;
  2. Длина строки ограничена ~ 250 символами.

В примере 5.3 иллюстрирована работа функции cgets.

Пример 5.3

/* Пример ex05003.c */
/* Определение констант - длины буфера */
#define LETTER_SIZE	50 // Максимальное число символов
#define BUFF_SIZE		55 // Общий размер буфера = LETTER_SIZE+5
/* Объявление переменной буфера */
char *buff[BUFF_SIZE];
char csize; //служебная переменна
/* Подготовительные операции и чтение с клавиатуры в буфер */
csize = BUFF_SIZE - 2; // Истинный размер буфера в символах
buff[0] = csize;	// Заносим это значение в буфер;
(void) cgets( buff );	// Читаем с клавиатуры в буфер
if( buff[1] > LETTER_SIZE ) goto ERROR; // Если переполнение буфера, следуем за ссылкой ERROR.

Благодаря механизму дескрипторов (двух первых "служебных" байтов строки-буфера) "переполнения буфера" достичь действительно сложно. MS-DOS просто не допустит чтения большего числа символов, чем это указано в байте buff[0].

ФУНКЦИЯ CSCANF
ОПИСАНА В: <conio.h>
СИНТАКСИС:
int cscanf( format {, argument} );
char *format;
НАЗНАЧЕНИЕ: Функция cscanf читает данные с консоли, выполняет форматные преобразования и помещает значения в переменные, адреса которых определяются аргументами функции.
ЗАМЕЧАНИЯ:
  1. Функция cscanf использует функцию getche для ввода символов;
  2. Каждый аргумент должен указывать на переменную того типа, который соответствует её описанию в строке: "format". См. также описание функции scanf, в приложении №II (6.7) к "Буферизированный (потоковый) ввод-вывод" .
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ:
  • количество элементов ввода, которые были успешно преобразованы и присвоены;
  • значение EOF, если встретился символ - признак конца файла;
  • 0, если нет присвоенных областей.

Пример: 5.4.

int i; // Целая переменна
/* Строка формата для ввода целого числа, состоящего из 10 знаков */
const char format[] = "%10d";
int ierr; // переменная ошибки ввода
/* Ввод значения с консоли */
ierr = cscanf( format, &i );
if( ierr != 1 )goto ERROR; // переход, если ошибка ввода
ФУНКЦИЯ GETPASS
ОПИСАНА В: <conio.h>
СИНТАКСИС:
char *getpass( prompt );
char *prompt;
НАЗНАЧЕНИЕ: Функция getpass используется для ввода с консольного терминала пароля, который оператор должен набрать в ответ на выводимое на экран приглашение, задаваемое строкой prompt с завершающим символом "\0". При вводе пароля отключается эхопечать вводимых с терминала символов.
ЗАМЕЧАНИЕ: длина пароля составляет не более 8 символов.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: указатель на строку с завершающим нулём, содержащую не более восьми первых символов текста.

ПРИМЕЧАНИЕ: Пароль хранится в статическом буфере (символьном массиве) функции и переписывается при каждом обращении к ней.

5.2.3. Консольный ввод в Quick Basic

Для ввода символов в Quick Basic используются одна функция и один оператор:

  • функция INKEY$ - для ввода символов без эхопечати;
  • оператор INPUT - для ввода значений, в том числе и форматированный ввод.

Рассмотрим эти функции поподробнее

ФУНКЦИЯ INKEY$
СИНТАКСИС: INKEY$
НАЗНАЧЕНИЕ: Функция для ввода символов с клавиатуры без эхопечати.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ:
  • пустая строка - символ не введён;
  • один байт с ASCII - символом - нажата алфавитно-цифровая клавиша;
  • два байта - нажата "серая" клавиша.

При этом левый байт будет всегда нулевой, а правый содержит расширенный скен ход клавиши.

Пример 5.5

REM ФАЙЛ: "EX05005.BAS"
REM ПРИМЕР ИСПОЛЬЗОВАНИЯ ФУНКЦИИ INKEY$
REM ОЖИДАЕМ НАЖАТИЯ КЛАВИШИ
100 C$ = INKEY$
IF C$ = "" GOTO 100
REM ПРОВЕРЯЕМ, НАЖАТА ЛИ "СЕРАЯ" КЛАВИША
IF LEN( C$ ) = 2 GOSUB 2000
…
REM "КОНСТРУКЦИЯ" ДЛЯ ОБРАБОТКИ СКЕН КОДОВ
2000 C$ = RIGHT( C$, 1 )
REM ПРЕОБРАЗУЕМ КОД В ЧИСЛО
C = ASC( C$)
REM НАЖАТА КЛАВИША "СТРЕЛКА ВЛЕВО"
IF C = 75 THEN GOSUB 3000
REM НАЖАТА КЛАВИША "СТРЕЛКА ВПРАВО"
IF C = 77 THEN GOSUB 3100
…
ОПЕРАТОР INPUT
СИНТАКСИС: INPUT аргумент
НАЗНАЧЕНИЕ: Оператор для форматированного ввода с клавиатуры с эхопечатью. Оператор автоматически переводит текст, набранный на клавиатуре, в формат, соответствующий формату вводимой переменной. Поддерживаются форматы:
  • вещественных чисел;
  • целых чисел;
  • символьных строк.
ЗАМЕЧАНИЯ:
  1. Ввод символов завершается нажатием клавиши "Enter" ; код ASCII 13 не добавляется в конец строки;
  2. До нажатия этой клавиши текст можно редактировать средствами редактирования строки DOS;
  3. Оператор "не воспринимает" "серые клавиши" на клавиатуре. Реакция на такое нажатие зависит от реализации Бейсика.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Нет.

Приведём пример ввода строки символов с консоли:

Пример 5.6

REM ФАЙЛ: "EX05006.BAS"
REM ПРИМЕР ИСПОЛЬЗОВАНИЯ ФУНКЦИИ INPUT
REM ВЫВОДИМ ПОДСКАЗКУ И ВВОДИМ СТРОКУ
PRINT "Введите своё имя: ";
INPUT NAME$
PRINT "Рад познакомиться с Вами, "; NAME$
STOP
END

5.3. Резюме

Итак, Вы познакомились с основными "консольными" операциями по вводу-выводу символьных данных на консоль (клавиатуру и экран дисплея). Этот ввод-вывод является основным вводом-выводом MS-DOS, позволяющий "манипулировать" атрибутами дисплея и "прямым" чтением из буфера клавиатуры.

Однако на практике чаще используется потоковый ввод-вывод. Именно его мы и рассмотрим в следующем разделе.

Описание же скен-кодов клавиш клавиатуры и их обработки выходит за рамки данного курса.

< Лекция 4 || Лекция 5: 12 || Лекция 6 >
Artem Bardakov
Artem Bardakov
Россия
Андрей Алабин
Андрей Алабин
Россия