Решение практических задач на Паскале. Выпуск 4
Представляю обещанный в прошлый раз http://www.borlpasc.narod.ru/Boris/solve003.htm третий способ хранения данных для программы во внешнем файле. Как отмечалось, его удобно использовать тогда, когда данных много и и их можно объединить в смысловые группы.
Пример входного файла, который я назвал Solv004.ini, приведен ниже:
# Файл исходных данных для простой программы, # которая вычисляет табличку функции Sin(x) и записывает # в файл, демонстрируя третий способ организации # входных данных # Входные данные для расчетов описываются в порядке: # левая граница, правая и шаг, с которым необходимо выполнить # вычисления. # Разделитель целой и дробной части - ТОЧКА 0.25 см, 34.5 см, 4 см # Имя файла, в который необходимо выводить результаты вычисления # НЕЛЬЗЯ использовать специальные символы. Желательно не указывать # путь к файлу. Тогда он будет создан в той папке, из которой # будет запущена программа Solv004.out
Как видите, символ "#" служит индикатором того, что это строка - комментарий, и при анализе содержимого файла будет пропущена. Это позволяет писать в ней все, что нужно, не стесняясь в выражениях и не задумываясь о том, сколько места этот комментарий занимает :))
За основу анализирующей программы я взял тот же вариант, что был описан в предыдущем случае. Только переписал процедуру ReadData. По-прежнему она использует процедуру FindReal, описанную в модуле MyIO003.pas.
Внимание:
Тестирование показало, что в процедуре FindReal нужно изменить строчку:
if NBeg = len then EXIT; { Все, дошли до конца строки, а цифр не нашли. Выходим и код ошибки уже установлен }
Знак "=" ( равно) нужно заменить на ">" (больше). Иначе, если последний символ - одна цифра, то он пропускается!
if NBeg > len then EXIT;
Я приведу текст только процедуры чтения данных. В ней предполагается, что данные, как и раньше, записаны в определенном порядке. Строки, начинающиеся с символа "#" не анализируются.
В процедуре ReadData нужно проанализировать несколько строк. Поэтому добавлена переменная, в которой храним номер анализируемой строки. Для анализа строки с нужным номером используется оператор Case. Выделены операторы Continue и Break, которые используются для упрощения кода. К сожалению, "некоторые" вместо них используют метки. А это не есть хорошо!
function ReadData(AFileName: String;
var Left, Right, Step: Real;
var AName: String): Boolean;
var
ini: Text;
buf: String;
nString: Integer; {Нужно, чтобы определить, какая это строка
с параметрами:
первая значащая - в ней границы,
вторая - в ней имя файла}
k, opCode: Integer;
{Вспомогательная функция, облегчающая работу.
Возвращает значение ИСТИНА, если это строка - комментарий
(первый символ - "#" ) или пустая}
function IsComment(str: String): Boolean;
begin
IsComment:=True;
{Пропустим первые симовлы - пробелы}
while (str[1]=' ') and (length(str)>1) do delete(str, 1, 1);
if str = '' then Exit; {пустая - точно нет данных}
IsComment := str[1] = '#'
end;
begin
ReadData:=False; Assign(ini, AFileName); {$I-} Reset(ini); {$I+}
if IOResult <> 0 then begin
WriteLn('Не могу открыть файл с исходными данными:');
WriteLn(AFileName); Exit;
end;
ReadData := TRUE;
Left := 0; Right:= 1; Step := 0.1;
AName:= 'out004.dat'; {Значение по умолчанию}
nString:=1;
while NOT EOF(ini) do begin
ReadLn(ini, buf);
if IsComment(buf) then Continue;
{Эта часть будет пропущена, если buf опознана как комментарий}
k:=1;
Case nString of
1: begin
inc(nString);
FindReal(buf, Left, k, opCode); if OpCode <> 0 then Break;
FindReal(buf, Right, k, opCode); if OpCode <> 0 then Break;
FindReal(buf, Step, k, opCode); if OpCode <> 0 then Break;
end;
2: begin {Нужно только удалить возможные пробелы.
Мы пишет программу под ДОС - там длинные имена не
разрешены}
inc(nString); {чтоб больше не анализировалось ничего}
while pos(' ', buf) <> 0 do delete(buf, pos(' ',buf), 1);
if buf <> '' then AName:=buf
end;
end;
end;
Close(ini);
end;
Да, еще я изменил код "вычисляющего" цикла в теле программы так, чтобы значение, соответствующее "правой" границе
вычислялось даже тогда, когда начальное значение и шаг таковы, что в правую (большую) границу
Свои вопросы и предложения присылайте Борису
Мы приглашаем Вас и Ваших друзей к сотрудничеству. Напишите, какая проблема Вас лично интересует - и мы постараемся помочь Вам. Поделитесь со всеми, если Вам удастся найти красивое решение. Присылайте свои программы, и если они хороши, то опубликуем их с обязательным указанием Вашего авторства.
По всем вопросам можно писать
либо в Гостевую книгу нашего сайта на www.turbopascal.tk, либо мне,
Рассылка поддерживается сайтом www.turbopascal.tk. При перепечатке ссылка на сайт обязательна
Внимание: сессия и экзамены еще не начались - самое время подписаться на нашу рассылку:
|