Главная » Free Pascal » Ввод/вывод данных простого типа Free Pascal

0

Из ряда программ, приводившихся в предыдущих разделах, вы заметили, что ввод осуществляется с помощью процедур read (от англ. read — читать) и readln (от англ. read line — читать строку), вывод — с помощью процедур write (от англ. write — писать) или writeln. Добавка символов ln означает, что после выполнения соответствующей операции курсор на экране дисплея переводится в начало сле- дующей строки.

Каких-то особенностей при вводе числовой информации в процедурах read/readln нет. Их операндами являются имена переменных всех числовых типов, а к набору на клавиатуре соответствующих значений предъявляются естественные требования:

± тип значения должен соответствовать типу переменной (единственное исклю- чение делается для данных вещественных типов, вводимые значения для кото- рых могут быть и целочисленными);

± пробелы в набираемых значениях не допустимы, любой пробел воспринимает- ся как разделитель между данными (подряд идущие пробелы эквивалентны од- ному пробелу);

± набор значений завершается по нажатию клавиши <Enter>.

Количество переменных в операторе ввода не обязательно должно соответство- вать количеству значений, набираемых пользователем на клавиатуре. Если пере- менных больше, то после получения сигнала <Enter> программа будет ждать до- ввода недостающих значений. Если количество набранных значений превышает число аргументов процедуры ввода, то лишние данные могут остаться в буфере ввода и будут востребованы при выполнении следующей операции read/readln. Но могут и пропасть, если предшествующий ввод был реализован по процедуре readln. Приведенный в листинге 4.6 пример демонстрирует разные сочетания двух смежных процедур ввода с превышением количества набираемых значений.

   Листинг 4.6. Программа  input1                                               

program input1; var

x: integer; y: real;

begin

write(‘x=’); {приглашение ко вводу}

read(x); writeln(‘x=’,x); read(y); writeln(‘y=’,y);

write(‘x=’); {приглашение ко вводу}

read(x); readln(y); writeln(‘x=’,x);

writeln(‘y=’,y);

write(‘x=’); {приглашение ко вводу}

readln(x); read(y); writeln(‘x=’,x);

writeln(‘y=’,y);

readln; end.

Результат работы программы input1 отображен на рис. 4.6. После каждого приглашения ко вводу пользователь набирал два числа вместо одного. В двух пер- вых случаях второе число сохранилось в буфере ввода и было востребовано про- граммой без дополнительного набора значения переменной y. В третьем случае лишнее число "пропало" и значение y пришлось набирать заново.

Рис. 4.6. Результат перебора на вводе

Без дополнительных указаний о форме вывода вещественных данных типа double система использует формат по умолчанию — у мантиссы выводится 15 значащих цифр (первая в целой части) и десятичный порядок (после буквы E), со- держащий знак порядка и три его цифры. Мантисса должна быть умножена на 10 в степени порядка. Эта форма вывода не всегда бывает удобной, и чаще всего дан- ные вещественного типа выводят в формате с фиксированной точкой, указывая при этом общую длину числа n (число позиций, выделяемых под выводимое значение на экране) и количество m цифр в его дробной части:

writeln(‘y=’,y:n:m);

При этом выводимое число прижимается к правой границе отведенного поля и округляется с учетом (m+1)-й цифры в дробной части: если эта цифра не менее 5, то к m-й дробной цифре добавляется единица. В примере, приведенном выше, можно было бы задать n=4 (в общем числе позиций надо не забывать о знаке числа и точ- ке, отделяющей целую часть от дробной) и m=1. Если количество позиций, остаю- щихся под целую часть, оказывается недостаточным, то система расширяет общую длину поля вывода и число выводится правильным. Однако в этом случае при вы-

воде таблиц некоторые значения могут смещаться, нарушая общую стройность ко- лонок.

Следующий пример вывода вещественных данных разного типа демонстрирует не только системные форматы по умолчанию, но и точность представления дан- ных. В программе pi_out выводится значение    (листинг 4.7).

   Листинг 4 .7 .  Программа  pi_out                                               

program pi_out; var

pi_s: single; pi_r: real; pi_d: double; pi_e: extended;

begin

writeln(‘pi_Calc=3.1415926535897932384626433832795′);

writeln(‘pi=   ‘,pi); pi_s:=3.1415926535897932384626433832795; pi_r:=3.1415926535897932384626433832795; pi_d:=3.1415926535897932384626433832795; pi_e:=3.1415926535897932384626433832795;

writeln(‘pi_s= ‘,pi_s); writeln(‘pi_r= ‘,pi_r); writeln(‘pi_d= ‘,pi_d); writeln(‘pi_e= ‘,pi_e); readln;

end.

Результат ее работы приведен на рис. 4.7.

Рис. 4.7. Вывод вещественных данных по умолчанию

Величина , принятая за эталон точности и содержащая 31 цифру в дробной части, скопирована из калькулятора Windows. Ее значение можно вывести только как строку символов. В переменной pi, которую компилятор рассматривает как системную функцию (а правильнее было бы называть ее системной константой), выведено 16 верных знаков после запятой. На самом деле, эта константа представ- лена в формате extended, сохраняющем не менее 19 десятичных цифр. Те же са-

мые 16 значащих цифр в дробной части мы видим и у переменной pi_e. Однако для переменных pi_r и pi_d формат по умолчанию предусматривает вывод 14 зна- ков после запятой (тип double гарантирует хранение 15—16 десятичных цифр). В формате single после запятой выводится 8 значащих цифр, но две последние не соответствуют точному значению. Вообще говоря, их выводить и не следовало, т. к. тип single гарантирует хранение не более 7—8 десятичных цифр.

Программа out_round демонстрирует не только режимы округления при выво- де вещественных данных, но и некоторые программистские трюки: задание нуле- вых значений n и m в формате вывода, прижим выводимых данных к левой границе поля при n<=0 (листинг 4.8).

Рис. 4.8. Управление форматом вывода

   Листинг 4 .8 .  Программа  out_round                                            

program out_round; var

x:extended=1.23456789; j:integer;

begin

for j:=0 to 9 do writeln(x:0:j);

for j:=0 to 9 do writeln(x:10:j);

for j:=0 to 9 do writeln(x:-10:j);

readln;

end.

Результат ее работы показан на рис. 4.8.

Приведенные варианты управления шириной поля применимы к выводу цело- численных данных и любой нечисловой информации.

С вводом значений символьных переменных дело обстоит несколько сложнее по двум причинам. Во-первых, символ "пробел" рассматривается как обычный ото- бражаемый символ, а не как разделитель вводимых данных. Во-вторых, от нажатия клавиши <Enter> в буфер ввода поступает управляющий символ с кодом 13. И все они наряду с обычными символами могут быть считаны из буфера. Об этом свиде- тельствует пример из листинга 4.9.

   Листинг 4.9. Программа  input2                                               

program input2; var

ch1:char=’1′;

ch2:char=’2′;

ch3:char=’3′; begin

writeln(‘ord(old ch1)=’,ord(ch1));

writeln(‘ord(old ch2)=’,ord(ch2));

writeln(‘ord(old ch3)=’,ord(ch3)); write(‘ch1=’); readln(ch1,ch2,ch3); writeln(‘ord(new ch1)=’,ord(ch1));

writeln(‘ord(new ch2)=’,ord(ch2));

writeln(‘ord(new ch3)=’,ord(ch3)); readln;

readln; end.

Результат работы представлен на рис. 4.9.

Рис. 4.9. Ввод данных типа char

Обратите внимание на то, что после приглашения к вводу были нажаты три клавиши — <Пробел>, <4> и <Enter>. Три соответствующих символа с кодами 32, 52 и 13 были извлечены из буфера клавиатуры при последующем выполнении опе- ратора readln(ch1,ch2,ch3).

Вообще говоря, ввод значений символьных данных правильнее организовывать

с  помощью  функции  ReadKey и  вводить  их  по  одному,  не  нажимая  клавишу

<Enter>. Нужно только не забыть подключить к своей программе модуль Crt, в ко- тором находится подпрограмма ReadKey (листинг 4.10).

   Листинг 4.10. Программа  input3                                              

program input3;

uses Crt;

var

ch1:char=’1′;

ch2:char=’2′;

ch3:char=’3′; begin

writeln(‘new ch1=’);

ch1:=ReadKey;

writeln(‘ord(new ch1)=’,ord(ch1)); writeln(‘new ch2=’);  ch2:=ReadKey;

writeln(‘ord(new ch2)=’,ord(ch2)); writeln(‘new ch3=’);

ch3:=ReadKey;

writeln(‘ord(new ch3)=’,ord(ch3)); readln;

readln; end.

Результат работы программы input3 приведен на рис. 4.10. В ответ на каждое приглашение к вводу были нажаты те же клавиши, что и в предыдущем примере —

<Пробел>, <4> и <Enter>. Но никакого следа на экране не осталось, т. к. в этом ре- жиме ввод происходит без эхо-сигнала. Именно так можно вводить секретные со- общения типа паролей.

Рис. 4.10. Ввод данных с помощью функции ReadKey

С помощью функции ReadKey вводят коды специальных клавиш, для которых не нашлось места в таблице ASCII. К таковым, в частности, относятся функцио- нальные клавиши <F1>, <F2>, … , "стрелки" управления курсором, клавиши редак- тирования (<Insert>, <Delete>, <Page Up>, <Page Down>, <Home>, <End>) и др. От их нажатия в буфер клавиатуры поступает так называемый скан-код, состоящий из двух байт. Первый байт, извлекаемый из буфера клавиатуры по функции ReadKey, при этом равен нулю (для обычных символов первый байт совпадает с кодом ASCII). И только по значению следующего байта, который извлекается повторным обращением к функции ReadKey, можно определить, какая из специальных клавиш была нажата. Вы можете составить нехитрую программу, которая будет выводить скан-коды интересующих вас клавиш.

Данные логического типа выводятся не так уж и часто: их главное назначе- ние — участие в формировании логических условий, управляющих ходом выпол- нения программы. Но, тем не менее, вывести их значения можно (листинг 4.11).

   Листинг 4.11. Программа  input4                                              

program input4; var

b1:boolean=true; b2:boolean=false;

begin

writeln(‘b1=’,b1,’ b2=’,b2); readln;

end.

Результат такого вывода представлен на рис. 4.11.

Рис. 4.11. Вывод логических данных

Однако вводить значения логических данных нельзя (такая попытка пресекает- ся компилятором). Их проще формировать в программе, действуя в соответствии с алгоритмом решения задачи.

Данные перечислимого типа в операторах ввода/вывода использовать нельзя (такие попытки пресекаются компилятором). Поэтому приходится искать обходные пути. Например, для вывода можно воспользоваться оператором выбора (переклю- чателем) — листинг 4.12.

   Листинг 4.12. Программа  input5                                              

program input5; type

RGB=(red,green,blue);

var

a:RGB=green; begin

case a of

red : writeln(‘a=red’); green: writeln(‘a=green’); blue : writeln(‘a=blue’);

end; readln;

end.

Образец вывода показан на рис. 4.12.

Рис. 4.12. Вывод значений перечислимого типа

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

Источник: Кетков, Ю. Л., Свободное программное обеспечение. FREE PASCAL для студентов и школьников, Ю. Л. Кетков, А. Ю. Кетков. — СПб.: БХВ-Петербург, 2011. — 384 с.: ил. + CD-ROM — (ИиИКТ)

По теме:

  • Комментарии