Песни о Паскале
Шрифт:
• Ввод массива из текстового файла и вывод в него возможен только поэлементно, для чего организуют цикл.
А слабо?
А) Массив A и переменная C объявлены так:
var A : array [’a’..’z’] of integer;
C: char;
Допустимо ли такое объявление массива и почему? Сколько элементов содержит массив? Какие из указанных ниже операторов будут (или могут) вызывать ошибки нарушения диапазонов?
A[’s’]:= 10;
A[’R’]:= 10;
C:=’d’; A[C]:= 10;
Readln(C); A[C]:= 10;
Проверьте свои решения на практике.
Глава 40
Пристрелка на знакомых мишенях
Итак, из арсенала Паскаля мы извлекли ещё одно мощное оружие – массивы. Опробуем его на знакомых мишенях, – некоторые наши программы можно улучшить, например, программу «вопрос-ответ» или полицейскую базу данных.
Вопрос-ответ – добиваемся гибкости
В 16-й главе мы смастерили шуточную программку, невпопад отвечающую на вопросы пользователей. Жаль только, что ответы намертво вбиты в саму программу. Скоро пользователям надоест смеяться над одним и тем же, и они забросят игрушку. Так пусть ваши приятели сами сочиняют смешные ответы и помещают их в текстовый файл, и тогда программа при запуске будет загружать их оттуда.
Прежде всего, подумаем над размещением вводимых из файла строк, где поселить их? «В массиве строк», – скажете, и будете правы. А сколько элементов запасти в этом массиве? Чем больше, тем лучше? Некоторые компиляторы накладывают ограничение на размер массива, но сотню строк они позволят, и этого пока достаточно. Итак, для хранения ответов объявим массив из 100 строковых переменных.
Перейдем к процедуре ввода этих строк. Техника ввода массива рассмотрена в предыдущей главе. Но теперь надо ещё и подсчитать введенные строки, иначе в дальнейшем мы не всегда сможем правильно индексировать массив, — ведь фактическое количество строк в файле может быть и меньше ста. С этой целью объявим переменную Fact, в которой и сделаем нужный нам подсчёт.
Обсудив эти моменты, обратимся к программе «P_40_1».
{ P_40_1 – Программа "вопрос-ответ" с применением массива }
const CAnswers = 100; { размер массива с ответами }
{ объявление типа для массива ответов }
type TAnswers = array[1..CAnswers] of string;
var Answers : TAnswers; { объявление массива ответов }
Fact : integer; { фактическое количество ответов }
F : text; { файл с ответами }
S : string; { строка с вопросом }
{ Процедура ввода ответов из файла с подсчетом введенных строк }
procedure ReadFromFile(var aFile: text);
var i: integer;
begin
Fact:=0; { для начала подсчета строк обнуляем счетчик }
{ цикл по массиву строк }
for i:=1 to CAnswers do begin
if Eof(aFile) then Break; { если конец файла – выход}
Readln(aFile, Answers[i]); { читаем строку в элемент массива }
Fact:= Fact+1; { наращиваем счетчик строк }
end;
end;
begin {--- Главная программа ---}
Assign(F, 'P_40_1.in'); Reset(F);
ReadFromFile(F);
Close(F);
Randomize; { чтобы порядок вопросов не повторялся }
{ Начало главного цикла }
repeat
Write('Введите вопрос: '); Readln(S);
if S<>'' then Writeln(Answers[Random(Fact)+1]);
until S='';
end.
Открыв файл ответов «P_40_1.IN», мы вызываем процедуру ReadFromFile (читать из файла), которая загружает строки в массив Answers (ответы). Она же подсчитывает введенные строки в переменной Fact. Таким образом, если файл содержит больше сотни строк, то в массив попадёт первая сотня, а иначе — столько, сколько там есть фактически, и это количество покажет переменная Fact. Дальше всё работает, как в прежнем варианте: после ввода вопроса ответ случайным образом выбирается из массива. Индекс элемента с ответом определяется выражением Random(Fact)+1. Если помните, функция Random(Fact) возвращает значения в диапазоне от 0 до Fact-1, а индексы нашего массива начинаются с единицы.
Полицейская база данных – ускоряем поиск
А теперь освежите в памяти другое наше творение – программу поиска угнанных автомобилей в полицейской базе данных (глава 29). Её слабость в том, что поиск номеров выполняется в текстовом файле. Ах, если б вы знали, как «тормозит» такой поиск! Вы не заметили? Да, на десятках строк этого не ощутить, иное дело – сотни тысяч, или миллионы. Итак, перенесем список номеров из текстового файла в массив, и тогда поиск ускорится многократно!
В программе «P_40_2» обратите внимание на пропуск пустых строк в процедуре ReadFromFile. Если этого не сделать, счётчик Fact может оказаться на 1 больше, чем должно, – так случится, если за последним числом будут пустые строки. Следующий далее оператор чтения числа пренебрегает границами между строками, поэтому в одной строке допустимы несколько чисел.
{ P_40_2 – Полицейская база данных с применением массива }
const CNumbers = 1000; { размер массива с номерами автомобилей }
{ объявление типа для массива номеров }
type TNumbers = array[1..CNumbers] of integer;
var Numbers : TNumbers; { объявление массива номеров }
Fact : integer; { фактическое количество номеров в файле }
F : text; { файл с номерами }
Num : integer; { номер проверяемого автомобиля }
{ Процедура ввода номеров из файла }
procedure ReadFromFile(var aFile: text);
var i: integer;
begin
Fact:=0; { для начала подсчета номеров обнуляем счетчик }
for i:=1 to CNumbers do begin { цикл по массиву номеров }
while Eoln(aFile) do { Пропуск пустых строк }
if Eof(aFile) then Break else Readln(aFile);
if Eof(aFile) then Break; { если конец файла – выход из цикла }
Read(aFile, Numbers[i]); { читаем номер в элемент массива }
Fact:= Fact+1; { наращиваем счетчик номеров }