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

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

>30 -- TRUE

>100 -- FALSE

>200 -- FALSE

>300 -- TRUE


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

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



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

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

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

Барабаним по клавишам

Теперь все готово для сочинения задуманной программы «P_30_1», ниже показан её текст. В начале программы объявлены три глобальные переменные: две – для доступа к входному и выходному файлам, и одна – для подсчета читаемых строк. Поскольку эти переменные объявлены перед процедурой обработки строки HandleString, то будут видны и в этой процедуре. Поэтому передавать содержащиеся в них данные через параметры здесь не обязательно (но возможно). Таким образом, мы передаем данные в процедуру через глобальные переменные, – в небольших программах это допустимо. Только не злоупотребляйте этим приемом, иначе в сложных программах запутаетесь.

Заглянем теперь внутрь процедуры HandleString. Кстати, её название составлено из двух слов: Handle – «обработка», и String – «строка». Процедура не принимает параметров, поскольку все необходимые данные получает через глобальные переменные. Обратите внимание на вычисление среднего балла:


>      Rating:= Sum div Cnt;


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

А что сказать о главной программе? Она работает по ранее рассмотренному алгоритму. По крайней мере, сейчас нам так кажется.


>{ P_30_1 – обработка журнала, первый вариант }

>      {----- Глобальные переменные -----}

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

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

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

>procedure HandleString;

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

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

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

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

>begin

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

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

>      Read(InFile, N);       { читаем оценку в переменную N }

>      Sum:= Sum+N;       { накапливаем сумму баллов }

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

>      end;

>      if Cnt>0

>      then begin       { если оценки были }

>      Rating:= Sum div Cnt;

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

>      end

>      else { а если оценок не было }

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

>end;


>      {----- Главная программа -----}

>begin

>      Counter:= 0;       { обнуляем счетчик строк }

>      { открываем входной файл }

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

>      { создаем выходной файл }

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

>      { выводим шапку таблицы }

>      Writeln(OutFile, 'Номер Количество Сумма Средний');

>      Writeln(OutFile, 'ученика оценок       баллов балл');

>      { пока не конец входного файла… }

>      while not Eof(InFile) do begin

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

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

>      end;

>      { закрываем оба файла }

>      Close(InFile); Close(OutFile);

>end.


Скомпилировали программу? Тогда подготовьте входной файл с оценками учеников (без фамилий). Назовите его «P_30_1.in» и сохраните, как обычно, в рабочем каталоге. Можно запускать? В общем-то, да. Но будьте настороже, – ошибки караулят нас на каждом шагу! Возьмите за правило первый прогон своих программ выполнять в пошаговом режиме. Поступим так и в этот раз.

Первый блин

Переключитесь в окно программы и для исполнения одного шага нажмите клавишу F7. Продолжайте нажимать её, наблюдая за ходом выполнения операторов. При желании добавьте в окно обзора переменных «Watch» глобальную переменную Counter.

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


>      while not Eoln(InFile)


уже не выполняется ни разу, и в выходной файл пишется «Ученик не аттестован». Ещё загадочней другой фокус: не выполняется условие выхода из цикла в главной программе.


>      while not Eof(InFile)


Обработав несколько строк, программа почему-то продолжает фанатично работать и дальше; она, как говорится, зациклилась. Если бы мы запустили её сразу в непрерывном режиме, то захламили бы выходным файлом весь диск! Пришлось бы аварийно снимать программу диспетчером задач. Ясно, что где-то притаилась ошибка, и надо прервать выполнение программы. Сделать это в пошаговом режиме несложно, – нажмите комбинацию Ctrl+F2.


Рекомендуем почитать
Зеркала

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


Шептунья

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


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

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


Когда цветет ликорис

Что делать, если проснулась в морге и понятия не имеешь, как могла в нем оказаться? Но страшно даже не это. Что делать, когда память подвела настолько, что неясно даже - кто ты?! В голове остались лишь странные имена, а ночью снятся слишком реальные сны. А потом... черт, да как же я могла такое забыть?! Я же ведьма!!! И у меня любовь с оборотнем, которого еще спасти надо. А заодно и целое королевство, иначе им завладеет беспощадный злодей. Вот только, это совсем другой мир... Хорошо, что ликорис уже зацвел!


Послание в бутылке. Стихи

Данная книга содержит избранные произведения поэтессы за период 2007—2016 гг. Это философская, любовная, пейзажная лирика, проникнутая трепетным отношением к природе, восхищением красотой человеческой души.


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

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