Уважаемые подписчики! Извиняюсь за долгое (мягко говоря) молчание
Семестр выдался, однако ... И, тем не менее, начинаю.
Во-первых, чему будет посвящена эта рассылка, точнее, чему я хочу ее посвятить:
Сейчас расскажу, как можно хранить исходные данные для программы во внешнем файле. По-моему, этим приемом школьники и начинающие студенты все еще редко пользуются. Предпочитают писать:
Write('Введите значение какой-нибудь фигни'); ReadLn(Fignja);А тем не менее, производя расчеты с помощью ЭВМ удобно, чтобы вся информация, необходимая для вычислений, содержалась в отдельном файле, из которого Ваша программа ее считывает.
Причин несколько:
Исходные данные пусть содержатся в файле исходных данных в текстовом виде. Тогда изменять их можно с помощью любого текстового редактора.
Решим для определенности задачу: рассчитать значения некоторой функции в заданных пределах и с заданным шагом. Результаты записать в в виде таблицы в файл. (Когда я решал подобные задачи на Паскале, я пришел к разумному выводу, что одна и та же программа не должна и считать и отображать. Гораздо удобнее разделить функции. Отображать график функции, записанной в виде таблицы в текстовый файл, должна программа отдельная программа).
Код простенькой "решающей" программы. Пояснения в виде комментариев и ниже:
program Solv001; uses CRT; var inFileName: String; outFileName: String; a, b, h: Real; TYPE TMyFunction = function (xx: Real): Real; {Такой тип переменной, ее в Паскале называют "процедурным типом" позволит одной процедурой рассчитывать графики различных функций} function ReadParams: Boolean; const space = ' '; var F_TEXT: Text; begin ReadParams:=False; {Это значение по умолчанию} Assign(F_Text, inFileName); {$I-} Reset(F_Text); {$I+} if IOResult <> 0 then begin WriteLn('Не могу открыть файл ', inFileName); ReadKey; end; {При чтении тоже могут быть ошибки. Например, поставьте вместо "англоязычной" разделительной точки "русскоязычную" запятую или букву} {$I-} ReadLn(F_Text, a, b, h, outFileName); {$I+} if IOResult <> 0 then begin WriteLn('Произошла ошибка при чтении данных из файла', inFileName); Exit; end; {В outFileName будет занесено все, что идет после числа, в том числе и пробелы. Их надо удалить} While pos(space, outFileName) <> 0 do delete(outFileName, pos(space, outFileName), 1); Close(F_Text); {Закрывать файл лучше самому} ReadParams:=True {Вот теперь-то и ставим сигнал "Все прошло нормально" } end; {Рассчет и вывод} procedure CalcAndOut(Left, Right, Step: Real; Func: TMyFunction); var t: Text; begin Assign(t, outFileName); Rewrite(t); while Left < Right do begin WriteLn(t, Left,' ', Func(Left)); Left:=left + Step; if Left > Right then Left := Right; end; Flush(t); Close(t); WriteLn('Расчет и вывод в файл ',outFileName,' закончены') end; {Эту функцию будем рассчитывать} function MySin(x: Real): Real; far; begin MySin:=12*sin(3*x) end; BEGIN ClrScr; if ParamCount = 0 then begin WriteLn(' Программе нужно передать параметр: имя файла с данными'); WriteLn(' ПРИМЕР ЗАПУСКА:'); WriteLn(' >Solv001.exe solv.dat'); WriteLn('Для продолжения нажите любую клавишу ...'); ReadKey; WriteLn('Нет, нет, только не эту!'); Halt(1); end; inFileName:=ParamStr(1); if NOT ReadParams then begin WriteLn('Нужно имя существующего файла'); ReadKey; Halt(1) end; CalcAndOut(a, b, h, MySin); END.Когда запускаете программу из среды разработки программ Borland Pascal, то значение параметра следует задать с помощью меню Run/Parameters...
Если исполняемый файл запускаете в Windows, то значение параметра, файла с исходными данными следует указать в ярлыке, на закладе "Программа".
Программа должна считать данные, сообщить, какие значения параметров установлены и ждать Вашего решения, начинать расчеты или прекратить работу для исправлений.
Можно предложить 3 простых варианта организации файла данных. Для этого чтение исходных данных вынесено в отдельную функцию булевского типа. Я назвал ее ReadParams. Тело этой функции я буду менять, показывая другие алгоритмы чтения исходных данных. Эта функция возвращает значение ИСТИНА, если все удалось прочитать правильно, и ЛОЖЬ - если произошла какая-то ошибка
Варианты такие:
0.5 100 5.1 out.DATчто должно означать:
Считать все эти данные можно одним оператором ReadLn:
ReadLn(F_TEXT, a, b, h, outFileName);Именно это и сделано в примере, который показан выше.
Одна проблема - в outFileName будут считаны лишние пробелы, что для DOS недопустимо. Я удалил их с помощью стандартной функции POS
Данный вариант прост в программировании, но неудобен тем, что трудно бывает вспомнить, что на каком месте должно быть записано.
Другие, более сложные в программировании, но удобные для пользователя способы опишу в следующих выпусках
Вопросы и предложения присылайте Борису
К стати, а Вы знаете, что у нас имеется рассылка, посвященная самым новым и нужным шпаргалкам для студентов и школьников?