Ввод и вывод текстовой информации
Наиболее простые средства ввода символьных и строковых данных предлагают Паскаль и QBasic. Здесь достаточно указать в списке ввода имя переменной соответствующего типа:
INPUT A$
ИЛИ
var
c1:char;
s1:string;
readln(cl);
readln(s1);
В Си имеется довольно много возможностей для ввода одиночных символов и цепочек строк. Форматный ввод с помощью функции scanf использует для этой цели два спецификатора:
"%s" - при вводе строковых значений в массив типа char; "%с" - при вводе одиночных символов в переменную типа char. Например:
char c1,s1l[80];
scanf("%c",&c1l); // не забывайте указывать адрес переменной
scanf("%s",s1); // имя массива одновременно является адресом
Ввод символьных и строковых данных завершается после нажатия клавиши <Enter>, однако в переменную d поступит только один символ, а в массив si при этом будет введена начальная цепочка символов до первого пробела. В операторе форматного ввода пробел или несколько подряд идущих пробелов рассматриваются как признак конца информации, считываемой из очередного поля. Конечно, при наборе вы можете набрать в одной строке несколько символов или несколько слов, разделенных пробелами. Все они будут введены в системный буфер, выделяемый для работы функции scant (стандартный размер этого буфера позволяет набрать строку длиной до 128 символов, включая и разделители-пробелы). При последующих обращениях к функции ввода данные из буфера продолжают извлекаться до тех пор, пока не будут исчерпаны, после чего вновь придется продолжить набор на клавиатуре.
Конечно, такой способ ввода может доставить неприятности и привести к непредусмотренному продолжению работы программы. Понятно также, что для ввода одного символа не хочется нажимать две клавиши, а вводимые строки могут состоять и из нескольких слов. Поэтому ввод символьных данных лучше выполнять с помощью других процедур:
int c1;
c1=getch(); //Ввод кода нажатой клавиши без отображения
//соответствующего символа на экране
c1=getche(); //Ввод кода нажатой клавиши с соответствующего
//символа на экране
c1=getchar(); // Ввод кода нажатой клавиши вслед за нажатием
//клавиши Enter
Обратите внимание на то, что вводимый символ передается не в переменную типа char, а в двухбайтовую целочисленную переменную. Именно такие значения возвращают указанные выше функции. Вторая особенность их применения связана с разбиением клавиатуры на две категории клавиш — отображаемые и управляющие. Окраска клавиш не совсем точно передает принадлежность клавиши той или иной группе. Например, функциональные клавиши <F1>, <F2> ... <F12> имеют разный цвет, но все они относятся к категории управляющих. А клавиша <Enter>, несмотря на серую окраску, причислена к разряду обычных.
Дело в том, что при нажатии обычной клавиши в буфер входного потока (stdin) поступает единственный байт с ненулевым кодом. Именно он и извлекается при первом же обращении к одной из функций getch, getchar или getche. От нажатия управляющих клавиш в буфер stdin поступают два байта, первый из которых содержит нулевой код, а второй представляет уже собственно числовой код, соответствующий выбранной клавише. Для извлечения второго байта к этим функциям приходится обращаться повторно, и таким образом программа может проанализировать сложившуюся ситуацию.
Есть некоторые нюансы и при нажатии клавиши <Enter>. Так, функция getch сообщает, что нажата клавиша с числовым кодом 13, а функция getchar считает, что последним введен символ с кодом 10. На самом деле она перекодирует код клавиши <Enter> в символ LF (line feed -- строка заполнена), действительно имеющий код 10 (0Х0А) в таблице ASCII. По-разному воспринимают эти функции и комбинацию <Ctrl>+<z>, сообщая в
одном случае, что поступил признак конца файла (end-of-file) с кодом 26, а в другом — что встретился признак EOF, которому соответствует числовой код — 1. Функция getchar не позволяет ввести код клавиши <Esc>, тогда как функции getch и getche успешно справляются с этой клавишей.
Зато с функций gets, осуществляющей ввод строки, у вас никаких проблем не возникнет:
gets (s);
Вы можете набирать любые предложения, содержащие любое количество пробелов, и все они будут введены в строку s. Однако длина вводимой строки ограничена емкостью буфера (128 байт).
Дополнительные возможности по вводу текстовых данных связаны с использованием потоков:
#include <iostream.h>
char c1, s1[80];
cin >> c1;
cin >> s1;
С выводом символьных и строковых значений все обстоит гораздо проще. В Паскале и QBasic достаточно в списке выводимых значений указать данные соответствующего типа:
PRINT А$,"Вася"
или
var
cl:char;
si:string;
writeln (c1, s1, .'Вася') ;
Форматный вывод в Си при помощи функции printf использует указанные выше спецификаторы, однако константные текстовые данные, которыми перемежаются выводимые значения, здесь располагаются между спецификаторами формата:
printf("%с Вася %s",c1,s1);
Вывод отдельного символа или одиночной строки в Си можно выполнить и c помощью
putchar (c1)
и
puts (s1)
Выводимое значение обычно располагается на экране, начиная с текущей позиции курсора. Если необходимо разместить текст в заранее предусмотренном месте, следует прибегнуть к одной из служебных процедур предварительного перемещения курсора в заданную позицию:
LOCATE col, row 'Так это выглядит на QBasicgotoxy(col,row);
// А так делается на Си и Паскале
Параметр col задает номер колонки в диапазоне от 1 до 80, а второй аргумент (row) определяет номер строки в диапазоне от 1 до 25.
Еще один способ управления по размещению текста связан с заданием ширины поля, отведенного под выводимое значение. Отображаемый текст, при этом прижимается к правой границе поля. Ширина поля в Паскале задается числовым выражением, которое записывается в операторе вывода через" двоеточие вслед за выводимым текстовым значением:
writelnt'Вася':10,c1:k+5,s1:7);
В QBasic для указания ширины поля используется оператор PRINT USING:
PRINT USING "##### ### #######";"Вася",А$,В$
В Си ширина поля включается в спецификатор формата ("%3с %10s"). Однако здесь имеется дополнительная возможность указать, что выводимое значение требуется прижать к левой границе выделенного поля ("%-Зс" %-10s").