Чтение и запись символов

Содержание

Самыми простыми из консольных функций ввода/вывода являются getchar(), которая читает символ с клавиатуры, и putchar(), которая отображает символ на экране. Первая из этих функций ожидает, пока не будет нажата клавиша, а затем возвращает значение этой клавиши. Кроме того, при нажатии клавиши на клавиатуре на экране дисплея автоматически отображается соответствующий символ. Вторая же функция, putchar(), отображает символ на экране в текущей позиции курсора. Вот прототипы функций getchar() и putchar():

int getchar(void);
int putchar(int c);

Как видно из прототипа, считается, что функция getchar() возвращает целый результат. Однако возвращаемое значение можно присвоить переменной типа char, что обычно и делается, так как символ содержится в младшем байте. (Старший байт при этом обычно обнулен.) В случае ошибки getchar() возвращает EOF. (Макрос EOF определяется в <stdio.h> и часто равен -1.)

Что же касается putchar(), то несмотря на то, что эта функция объявлена как принимающая целый параметр, она обычно вызывается с символьным аргументом. На самом деле из ее аргумента на экран выводится только младший байт. Функция putchar() возвращает записанный символ или, в случае ошибки, EOF.

В следующей программе продемонстрировано применение getchar() и putchar(). В этой программе с клавиатуры вводятся символы, а затем они отображаются на другом регистре. То есть символы, вводимые на верхнем регистре, выводятся на нижнем, а вводимые на нижнем — выводятся на верхнем. Чтобы остановить программу, введите точку.

#include <stdio.h>
#include <ctype.h>

int main(void)
{
  char ch;

  printf("Введите какой-нибудь текст
          (для завершения работы введите точку).\n");
  do {
    ch = getchar();

    if(islower(ch)) ch = toupper(ch);
    else ch = tolower(ch);

    putchar(ch);
  } while (ch != '.');

  return 0;
}

(Эта программа не работает, правда, с кириллическими символами.)

Трудности использования getchar()


Использование getchar() может быть связано с определенными трудностями. Во многих библиотеках компиляторов эта функция реализуется таким образом, что она заполняет буфер ввода до тех пор, пока не будет нажата клавиша <ENTER>. Это называется построчно буферизованным вводом. Чтобы функция getchar() возвратила какой-либо символ, необходимо нажать клавишу <ENTER>. Кроме того, эта функция при каждом ее вызове вводит только по одному символу. Поэтому сохранение в буфере целой строки может привести к тому, что в очереди на ввод останутся ждать один или несколько символов, а в интерактивной среде это раздражает достаточно сильно. Хотя getchar() и можно использовать в качестве интерактивной функции, но это делается редко. Так что если предшествующая программа ведет себя не так, как ожидалось, то вы теперь знаете, в чем тут дело.

Альтернативы getchar()


Так как getchar(), имеющаяся в библиотеке компилятора, может оказаться неподходящей в интерактивной среде, то для чтения символов с клавиатуры может потребоваться другая функция. В стандарте языка С не определяется никаких функций, которые гарантировали бы интерактивный ввод, но их определения имеются буквально в библиотеках всех компиляторов С. И пусть в стандарте С эти функции не определены, но известны они всем! А известны они благодаря функции getchar(), которая для большинства программистов явно не подходит.

У двух из самых распространенных альтернативных функций getch() и getche() имеются следующие прототипы:

int getch(void);
int getche(void);

В библиотеках большинства компиляторов прототипы таких функций находятся в заголовочном файле <conio.h>. В библиотеках некоторых компиляторов имена этих функций начинаются со знака подчеркивания (_). Например, в Visual C++ компании Microsoft они называются _getch() и _getche().

Функция getch() ожидает нажатия клавиши, после которого она немедленно возвращает значение. Причем, символ, введенный с клавиатуры, на экране не отображается. Имеется еще и функция getche(), которая хоть и такая же, как getch(), но символ на экране отображает. И если в интерактивной программе необходимо прочитать символ с клавиатуры, то часто вместо getchar() применяется getche() или getch(). Вот, например, предыдущая программа, в которой getchar() заменена функцией getch():

#include <stdio.h>
#include <conio.h>
#include <ctype.h>

int main(void)
{
  char ch;

  printf("Введите какой-нибудь текст
          (для завершения работы введите точку).\n");
  do {
    ch = getch();

    if(islower(ch)) ch = toupper(ch);
    else ch = tolower(ch);

    putchar(ch);
  } while (ch != '.');

  return 0;
}

Когда выполняется эта версия программы, при каждом нажатии клавиши соответствующий символ сразу передается программе и выводится на другом регистре. А ввод в строках не буферизируется. И хотя в кодах в этой книге функции getch() и getche() больше не встречаются, но они вполне могут пригодиться в тех программах, которые напишете вы.



На заметкуТогда: когда писались эти слова, при использовании компилятора Visual C++ компании Microsoft функции _getch() и getch() были несовместимы с функциями ввода стандартного С, например, с функциями scanf() или gets(). Поэтому вам придется вместо стандартных функций использовать такие их специальные версии, как cscanf() или cgets(). Чтобы получить более подробную информацию, следует изучить документацию по Visual C++.