Практика программирования (Бейсик, Си, Паскаль)

       

Ввод и вывод текстовой информации


Наиболее простые средства ввода символьных и строковых данных предлагают Паскаль и 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").




Содержание раздела