Уважаемые подписчики! Извиняюсь за долгое (мягко говоря) молчание
Семестр выдался, однако ... И, тем не менее, начинаю.
Во-первых, чему будет посвящена эта рассылка, точнее, чему я хочу ее посвятить:
Сейчас расскажу, как можно хранить исходные данные для программы во внешнем файле. По-моему, этим приемом школьники и начинающие студенты все еще редко пользуются. Предпочитают писать:
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
Данный вариант прост в программировании, но неудобен тем, что трудно бывает вспомнить, что на каком месте должно быть записано.
Другие, более сложные в программировании, но удобные для пользователя способы опишу в следующих выпусках
Вопросы и предложения присылайте Борису
К стати, а Вы знаете, что у нас имеется рассылка, посвященная самым новым и нужным шпаргалкам для студентов и школьников?