Песни о Паскале - [58]

Шрифт
Интервал

Буква за буквой

Славный литературный герой Остап Бендер по поводу желанного миллиона сказал так: «Я бы взял частями, но мне нужно сразу!». Увы! При чтении фамилий надо проявить терпение. Если не получается сразу, возьмем по частям. Ведь строка фамилии состоит из отдельных букв, – так прочитаем фамилию по буквам! Прочитать букву может все та же процедура Read, например:


>var sym : char;

>...

>      Read(InFile, sym);       { чтение одного символа }


А фамилию S склеим из отдельных букв:


>      S:= S + sym;


Разумеется, что здесь нужен цикл, условием выхода из которого будет либо достижение первого пробела, либо достижение конца строки. В этом и состоит основная идея алгоритма, показанного на рис. 71.



Рис.71 – Упрощенный алгоритм побуквенного чтения фамилии
Нелишняя предосторожность

Людям свойственно ошибаться, – даже учителям! В строках журнала (а это текстовый файл) могут оказаться лишние пробелы – как между оценками, так и в начале строки, перед фамилией. И что тогда? – проверьте на практике. При чтении чисел процедура Read «не заметит» лишних пробелов, – она достаточно «умна». Другое дело – показанная выше блок-схема: если перед фамилией обнаружится пробел, то чтение слова завершится досрочно. Стало быть, для правильного чтения фамилии надо пропустить стоящие перед нею пробелы (если они есть). Это улучшение слегка усложнит блок-схему (рис. 72).



Рис.72 – Усовершенствованный алгоритм побуквенного чтения фамилии
Достройка программы

В основу новой версии программы «P_31_1» положим программу «P_30_1». Вам следует, прежде всего, открыть её и сохранить под новым именем. Готово? Тогда приступаем к правке.

Начнем с главной программы, где надо изменить имена входных и выходных файлов (чтобы не путать с похожими файлами предыдущей версии).


>      Assign(InFile,'Journal2.in');       Reset(InFile);

>      Assign(OutFile,'Journal2.out'); Rewrite(OutFile);


Позаботьтесь о том, чтобы файл «Journal2.in» был похож на настоящий классный журнал с фамилиями, как о нём сказано в начале 30-й главы.

Второе изменение внесем в процедуру обработки строки HandleString. Здесь объявим ещё одну переменную строкового типа, назовем её Fam, она будет вмещать фамилию ученика.


>      Fam:= ReadFam; { читаем фамилию }


Разумеется, оператор печати строки тоже будет изменен.


>      Writeln(OutFile, Counter:3, Fam:18, Cnt:8, Sum:14, Rating:11:1);


Осталось выяснить, что такое ReadFam? Это функция чтения фамилии, которую мы напишем по рассмотренному чуть выше алгоритму (рис. 72). Мой вариант функции таков.


>function ReadFam: string;

>var sym: char; { очередной символ }

>S : string; { накопитель строки }

>begin

>S:=''; { очистка накопителя строки }

>{ чтение символов до первой буквы }

>repeat Read(InFile, sym); until Ord(sym)>32;

>{ чтение последующих символов }

>repeat

>s:= s+sym;

>if Eoln(InFile) then Break;

>Read(InFile, sym);

>until not ((Ord(sym)>32));

>ReadFam:= S; { возвращаемый результат }

>end;


Обратите внимание на сравнение введенного символа с пробелом. Это сравнение можно было бы записать так:


>      sym <> ’ ’


Но пробел в кавычках трудно разглядеть. Лучше сравнивать код символа с кодом пробела (который равен 32), что и сделано внутри функции.

Испытание

Теперь все готово, запустите программу. Что оказалось в выходном файле «Journal2.out»? Наверное, вот это.


>Номер Фамилия       Количество       Сумма       Средний

>ученика       оценок       баллов       балл

>1       Акулова       3       12       4.0

>2       Быков       4       20       5.0

>3       Волков       4       18       4.5

>4       Галкина       3       10       3.3

>5       Крокодилкин       2       7       3.5


Если не считать кривых колонок, неплохо. Кривизну даёт разная длина фамилий учеников. Можно выровнять колонки, вычисляя спецификатор ширины в зависимости от длины фамилии. Или поступить иначе, – дополнить фамилии до одинаковой длины пробелами справа, например:


>      while Length(Fam) < 12 do Fam:= Fam + Char(32);


Этот оператор уместен после чтения фамилии. Окончательный вариант программы со всеми дополнениями и уточнениями представлен ниже.


>      { P_31_1 – Обработка классного журнала, второй этап }


>var InFile, OutFile : text; { входной и выходной файлы }

>    Counter: integer;       { счетчик строк в файле }


>{----- Функция чтения фамилии -----}


>function ReadFam: string;

>var sym: char;

>S : string;

>begin

>s:=''; { очистка накопителя строки }

>{ чтение символа до первой буквы }

>repeat Read(InFile, sym); until Ord(sym)>32;

>{ чтение последующих символов }

>repeat

>s:= s+sym;

>if Eoln(InFile) then Break;

>Read(InFile, sym);

>until not ((Ord(sym)>32));

>ReadFam:= S;

>end;

>      {----- Процедура обработки строки -----}


>procedure HandleString;

>var N : integer; { оценка, прочитанная из файла }

>      Cnt: integer; { количество оценок }

>      Sum: integer; { сумма баллов }

>      Rating: Real; { средний балл }

>      Fam: string; { фамилия }

>begin

>      Fam:= ReadFam; { читаем фамилию }

>      { для выравнивания столбцов добавляем пробелы }

>      while Length(Fam) < 12 do Fam:= Fam + ' ';

>      Sum:=0; Cnt:=0; { очищаем накопитель и счетчик оценок }

>      While not Eoln(InFile) do begin { пока не конец строки }


Рекомендуем почитать
Мое Черное Сердце

Его мир это ночь. Злой дух. Живой мертвец. Слуга тьмы. Он продал свою душу ради любви. И теперь каждую ночь ровно в полночь он приходит в этот мир чтобы убивать. Тысяча невинных душ это цена одной души… той единственной. Ради любви к которой он покончил с собой и заключил сделку с дьяволом. Но черная испепеляющая страсть не самое возвышенное чувство, за которое он выдавал свою любовь. Но есть ли время, чтобы это понять? Поздно начинать жить, когда ты уже мертв. Будет ли у него шанс почувствовать искреннюю нежность, которая не разольется жгучим ядом по его венам?.


Одержимые

"Да — я мисс Совершенство и меня зовут Кэрри Тимберли, мне шестнадцать"Так начинается история девушки, не знавшей, что в вскоре жизнь её измениться. Кэрри ждёт поступление в закрытую школу, под названием Кроуфилд. Только в той школе всё не так, как кажется на первый взгляд. Кэрри попытается узнать, и это приведет к неожиданным последствиям. Что за тайна, скрывается за стенами элитного учебного заведения "Воронье поле"?


Зеркала

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


Шептунья

Легко ли быть не такой как все? Безусловно, если твои магические силы вызывают восхищение, страх или любые другие сильные эмоции. Но если это всего лишь непонятная смесь странностей? Что делать? И как быть, если родной отец вдруг «продаёт» пугающему вампиру, совершенно не интересуясь твоим мнением? Быть женой ненавистного существа или же попытаться скрыться, устроив всем незабываемое прощание?


Фарг. Проблему решаю кардинально.

Два года! Два года сохнуть по нему и стесняться признаться... Отдых с подругой решит твою проблему!


Путешествие за счастьем

В далекой сказочной стране живут оборотни и люди, маги и демоны, орки и драконы. И сказки в ней случаются разные - добрые, веселые и даже страшные. А там где есть сказки, там обязательно есть счастье, а там где счастье, там должны быть феи.