Литмир - Электронная Библиотека

• Процедура Read после чтения затребованных данных продвигает позицию чтения за последний прочитанный элемент. Она подходит для последовательного чтения данных без учета разбивки на строки.

А слабо?

А) Напишите программу для преобразования второго варианта базы данных «Police.txt» (с несколькими числами в строке) в первый вариант (по одному числу в строке). Или слабо?

Б) Можно ли в решении предыдущей задачи назначить одно и то же имя как входному, так и выходному файлам? Испытайте на практике.

Глава 30

Журнальная история

Песни о Паскале (СИ) - _101.jpg

Статистика знает все?

Давно ли вы заглядывали в классный журнал? Хорошо бы делать это раньше своих родителей. Ах, если бы журнал можно было и править!.. Нет, я не подбиваю вас подтирать оценки! Мы всего лишь подвергнем журнал статистической обработке. Статистика – это наука, находящая закономерности в массе данных. Она как тот холм, взобравшись на который, за деревьями видишь лес. Нужен пример? Пожалуйста.

В некой школе некоторого царства-государства для сравнения учеников и классов учредили рейтинги. Что такое рейтинг? – это вроде места в турнирной таблице. Чем выше рейтинг, тем сильнее спортсмен или команда, то есть ученик или класс. Определять рейтинг условились по средней оценке ученика или всего класса. Так, совокупность многих оценок заменялась одним числом – средним баллом. Когда вместо десятков чисел получаешь одно, – это и есть плод статистической обработки.

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

Акулова 3 5 4

Быков       5 5 5 5

Воронов 4 5 5 4

Галкина 3 4 3

Крокодилкин 4 3

А вот что получалось после обработки его упомянутой программой.

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

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

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

Стало быть, средний балл вычислялся как частное от деления суммы баллов на количество оценок, а результат записывался с одним знаком после запятой.

И все было хорошо, пока вирусная атака не уничтожила бесценную программу. А где распечатка исходника? Увы, к тому времени её погрызли мыши! Друзья, теперь надежда только на вас, выручайте школу!

Строим планы

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

3 5 4

5 5 5 5

4 5 5 4

3 4 3

4 3

А в результате обработки мы должны получить такой выходной файл.

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

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

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

Набросаем план предстоящего сражения, то есть блок-схемы алгоритмов. На рис. 68 показан алгоритм главной программы. Он очень похож на тот, что применялся при шифровании текста, и это объяснимо: и там, и здесь выполняется построчная обработка файла.

Песни о Паскале (СИ) - _102.jpg

Рис.68 – Алгоритм главной программы

Рванув со старта, программа открывает входной файл, создает выходной и пишет туда заголовок таблицы – так называемую шапку. По окончании обработки оба файла будут закрыты. В этом алгоритме предусмотрен также и подсчет строк входного файла, необходимый для нумерации учеников в выходном файле.

Разобравшись с главной программой, сосредоточимся на обработке отдельной строки. Здесь заметно сходство со вторым вариантом полицейской базы данных (глава 29). И там, и тут читается ряд чисел, размещенных в одной строке. Но если в полицейской программе нам было безразлично, где кончается строка, то теперь иное дело, – ведь на следующей строке расположены оценки другого ученика! Нужен признак, сообщающий о достижении конца читаемой строки. Где его взять?

Ну, вы же понимаете, – в Паскале предусмотрено все! Познакомьтесь с функцией булевого типа по имени EoLn (от английского End of Line, что значит «конец строки»). Заголовок этой функции выглядит так:

      function Eoln(var aFile: text): boolean;

Функция принимает параметр – ссылку на текстовый файл – и возвращает TRUE, если позиция чтения в этом файле достигла конца строки. Она похожа на функцию Eof, проверяющую достижение конца файла. Исследуем функцию следующей программкой.

{----- Программа для исследование функции Eoln -----}

var F: text; N: integer;

begin

      Assign(F, 'Police.txt'); Reset(F);

      while not Eof(F) do begin

      Read(F, N); { чтение числа }

      Writeln(N, ' -- ', Eoln(F)); { печать признака конца строки }

      end;

      Close(F); Readln;

end.

Здесь из файла «Police.txt» читаются все числа, при этом печатаются и сами числа, и признак конца строки. Предположим, файл «Police.txt» содержал такие строки.

1 2 3

10 20 30

100 200 300

Тогда на экране явится вот что.

1 -- FALSE

2 -- FALSE

3 -- TRUE

10 -- FALSE

20 -- FALSE

30 -- TRUE

100 -- FALSE

200 -- FALSE

300 -- TRUE

Как видите, после чтения последнего числа в строке признак её окончания равен TRUE.

Теперь, когда мы нащупали конец строки, соорудим алгоритм обработки одной строчки входного файла (рис. 69).

Песни о Паскале (СИ) - _103.jpg

Рис.69 – Блок-схема обработки одной строки входного файла

Основу алгоритма составляет цикл чтения чисел, в ходе которого наращиваются счетчик оценок и их сумма. На входе в цикл и счетчик, и сумма очищаются, то есть, загружаются нулями. Выход из цикла происходит при достижении конца строки, и тогда в бой вступает условный оператор. Он исследует счетчик оценок, и, если оценок в строке не было, выводит в выходной файл сообщение «ученик не аттестован», а иначе печатает средний балл.

Кстати, годится ли для чтения строки оператор цикла REPEAT-UNTIL? Правильный ответ – нет. Если текущая строка окажется пустой, следующая оценка прочитается уже на следующей строке, а это не то, что нам нужно! Оператор WHILE – единственно правильное решение.

43
{"b":"596178","o":1}