На этом шаге мы рассмотрим организацию ввода данных с клавиатуры.
Рассмотрим некоторые полезные программы для работы с символьными данными, использующие условные конструкции. Символьные данные в языке С имеют тип char: переменная, которая будет содержать один символ (точнее - его код по таблице кодирования символов ASCII), должна описываться как char c, где c - имя переменной.
Среда VC++ обладает еще одним типом данных для описания символа, но по таблице Юникод. В отличие от таблицы ASCII, в соответствии с которой код символа занимает один байт, кодирование по Юникоду размещает символ в двух байтах. С таким кодированием мы встретимся позднее.
Компилятор C++ трактует переменные типа char как signed char (символьная со знаком) и как unsigned char (символьная без знака), причем подразумевается, что это данные разных типов. По умолчанию переменные типа char рассматриваются компилятором как переменные типа signed char. Такие переменные могут преобразовываться в переменные типа int.
Теперь после введения типа char можно определить и тип short или short int. Этим типом описывают "короткие" переменные целого типа. Такие переменные занимают памяти больше или равно, чем переменные типа char, и меньше или равно, чем переменные типа int.
В библиотеке С наряду с функциями _getch() и printf(), с которыми мы познакомились ранее, существуют и другие функции ввода/вывода. Две из них - это getchar() и putchar(). К переменной c эти функции применяются так:
c=getchar(); putchar(с);
Функции getchar() и putchar() описаны в файле stdio.h, который в данной версии среды не подключается к заготовке консольной программы автоматически. Первая функция не имеет параметров - в круглых скобках ничего нет. Функция getchar(), начав выполняться, ожидает ввода символа с клавиатуры. Как только символ с клавиатуры введен, его значение присваивается переменной с.
Если говорить точнее, функция getchar() работает несколько иначе. Фактическая обработка символа начнется только тогда, когда ввод закончится нажатием клавиши Enter, а до этого вводимые символы накапливаются в буфере функции. Поэтому если присвоение символов происходит в некотором цикле (например, если мы хотим сформировать строку из символов, вводя их через функцию getchar() по одному символу в цикле), то следует ввести всю строку символов, нажать клавишу Enter, и только тогда мы увидим результат ввода - строка будет состоять из символов, введенных функцией.
Тут возникает вопрос: а как дать знать программе, что ввод группы символов закончен? Ввод данных, как мы в дальнейшем увидим, может осуществляться и из файла. В этом случае на окончание ввода указывает так называемый признак конца файла, присутствующий в файле, который формируется функциями ввода файла после окончания его ввода в момент выполнения функции закрытия файла. Этот признак потом при чтении файла обнаруживается с помощью специальной функции _eof() (ее описание находится в файле <io.h>). Аббревиатура eof означает end of file.
Но как быть с признаком конца ввода при вводе данных с клавиатуры? Хотелось бы, чтобы и при вводе с клавиатуры был бы такой же порядок формирования признака конца данных. И он действительно имеется: среда рассматривает ввод символов с клавиатуры в виде специального потока данных, который можно завершить нажатием комбинации клавиш Ctrl+Z. При этом формируется символ, значение которого равно -1. Этот символ и будет признаком конца данных, вводимых с клавиатуры функцией ввода. Когда мы в программе "поймаем" этот символ, то должны завершить ввод. Это и будет для нас eof. Но такой признак можно и самостоятельно сформировать в прорамме: задать в ней некий символ (например, знак вопроса (?)), который будет означать конец ввода с клавиатуры. Тогда при вводе символов последним надо будет набрать символ знака вопроса (?), а в самой программе проверять каждый введенный символ на совпадение его со знаком вопроса и при обнаружении такого совпадения завершать ввод.
Как мы теперь знаем, для того чтобы функция getchar() приступила к вводу каждого набранного на клавиатуре символа, надо после набора группы символов (т. е. строки) нажать клавишу Enter. Нажатию этой клавиши соответствует символ \n - символ перехода на новую строку. Если мы хотим ограничиться вводом строки, то признаком конца ввода файла можно считать \n.
Если же мы хотим вводить группу строк и после этого дать знать программе, что ввод завершен, то в.качестве признака конца файла можно использовать некий управляющий код (из диапазона 0-31 таблицы ASCII) или, как мы видели, какой-либо символ.
Если воспользоваться стандартным признаком конца файла (нажатием Ctrl+Z), то следует поступать так: после ввода последнего символа последней строки и нажатия клавиши Enter (чтобы функция getchar() начала обработку введенных символов) требуется нажать комбинацию клавиш Ctrl+Z, затем клавишу Enter (чтобы символ от Ctrl+Z попал на обработку и тем самым цикл while завершился), затем надо еще раз нажать клавишу Enter (для прохода функции _getch()).
Если обозначить символическую константу, задающую значение признака конца ввода с клавиатуры через eof, то, воспользовавшись директивой препроцессора #define, в начале программы ввода данных с клавиатуры мы можем написать:
#define eof -1 // признак конца ввода символов с клавиатуры
Здесь // - это признак комментария в программе на языке С. Такой знак ставится, если текст комментария занимает только одну строку. Если же ваш комментарий более длинный, то следует воспользоваться другой формой задания комментария - "скобками" (/* */). Весь текст между этими скобками можно располагать на многих строках. Например:
/* признак конца ввода
символов с клавиатуры */
А теперь приступим к составлению простейших программ работы с символьными данными.
На следующем шаге мы рассмотрим программу копирования символьного файла.