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

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

Теперь сядем на пенёк и поразмыслим, в чем дело? Ведь первый вход в процедуру отработан верно. Вспомните наше исследование функции Eoln: чтение последнего числа в строке устанавливает признак конца строки в TRUE. Значит, при повторном входе в процедуру обработки строки цикл while not Eoln(InFile) не должен выполняться ни разу, – так оно и происходит. Так вот где собака порылась, – мы застряли в конце первой строки!

Этим же объясняется и зацикливание в главной программе, – не проскочив первой строки, нам не достичь конца файла. Виновник найден? – да, и теперь поищем решение проблемы. После обработки строки нам надо всего лишь перескочить с конца текущей строки в начало следующей, ничего при этом не читая. На ум приходит процедура Readln, – ведь она любит это делать. Помните, как подвела она нас во второй версии полицейской базы данных? Зато теперь выручит! Где её вызвать? Сделаем это после выхода из процедуры HandleString, то есть в цикле главной программы. Теперь главный цикл будет выглядеть так:


>      while not Eof(InFile) do begin

>      Counter:= Counter+1; { наращиваем счетчик строк }

>      HandleString;       { обрабатываем строку }

>      Readln(InFile);       { переход на следующую строку }

>      end;


Процедуре Readln передана лишь файловая переменная InFile, поскольку никаких данных ей читать не надо. Стало быть, для исправления программы добавим лишь один оператор. Сделайте это и запустите программу в пошаговом режиме. Если пара строк будет обработана правильно, запустите её далее в непрерывном режиме.

Блин второй

Запуская программу, не ждите результатов на экране, – программа отработает молча. Для просмотра результатов откройте выходной файл «P_30_1.out». Сделайте это, не выходя из IDE: просто нажмите F3 и укажите имя файла. Вам откроется следующая картина.


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

>      оценок       баллов       балл

>13124

>24205

>34184

>43103

>5273


Что это? Вместо ожидаемых четырех колонок чисел мы видим только одну. Да и числа в ней несуразные! Откуда они взялись? Пробуем разгадать эту головоломку: первая цифра совпадает с порядковым номером строки: 1, 2, 3 и так далее. Вторая равна количеству оценок ученика: 3, 4, 4, 3, 2. Ага, значит, результаты правильные, только «слиплись» в одно число, – между числами нет пробелов. Кто виноват? Нет, не мы с вами, а этот оператор.


>      Writeln(OutFile, Counter, Cnt, Sum, Rating);


Его параметры разделены запятыми, и потому печатаются подряд, без пробелов. Вставить пробелы можно, например, так:


>      Writeln(OutFile, Counter,’ ’,Cnt,’ ’,Sum,’ ’, Rating);


Тут между числами печатаются три строковые константы, состоящие из пробелов, они и будут разделять числа между собой. Количество пробелов можно рассчитать заранее или подобрать опытным путем. Но есть лучшее решение.

Спецификатор ширины поля

Лучшее решение дают спецификаторы ширины поля. Это числовые выражения, задающие количество позиций для печати параметра. Их указывают за печатаемым параметром, причем параметр и спецификатор разделяются двоеточием, например:


>      W := 15;

>      Writeln(OutFile, Cnt : 10, Sum : W);


Здесь значение переменной Cnt будет напечатано на десяти символьных позициях, а значение переменной Sum – на пятнадцати (соответственно значению W).

Спецификаторы – это дополнительные параметры процедуры печати, придающие красоту выводимым результатам. Когда число требует меньше места, чем задано в спецификаторе, лишние позиции заполнятся пробелами, а нам того и надо. К тому же, спецификатор может выравнивать выводимые числа по левому, или правому краю колонки: положительное его значение выравнивает число по правому краю, а отрицательное – по левому. Спецификаторы применяют и к строковым выражениям.

Для нашего случая я подобрал следующие значения спецификаторов.


>      Writeln(OutFile, Counter:3, Cnt:13, Sum:14, Rating:12);


Исправьте заодно и этот оператор вывода в файл:


>      Writeln(OutFile, Counter:3, ' Ученик не аттестован');


Снова запустите программу и проверьте результат. Кстати, если вы не закрывали окно с выходным файлом «P_30_1.out», то по завершении программы IDE сообщит о том, что файл на диске был изменен, – это сделала ваша программа. Но в открытом окне все осталось по-прежнему, потому IDE спрашивает разрешение на обновление окна, – дайте положительный ответ кнопкой «Yes» и переключитесь в окно с файлом «P_30_1.out». Теперь вы увидите вот что.


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

>      оценок       баллов       балл

>1       3       12       4

>2       4       20       5

>3       4       18       4

>4       3       10       3

>5       2       7       3


Это почти идеальный результат. Осталась лишь одна шероховатость, – средний балл не содержит дробной части. Займемся этим вопросом.

«Развесные» числа

Обратимся к строке программы, где вычисляется средний балл.


>      Rating:= Sum div Cnt;


Здесь одно целое число делится на другое, и результат тоже получается целым. Куда же девается дробная часть? Увы, дробная часть отбрасывается. Куда отбрасывается, не знаю, но она теряется. Поэтому при целочисленном делении получаются, например, такие забавные результаты.


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

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


Одержимые

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


Зеркала

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


Шептунья

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


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

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


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

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