Решение практических задач на Паскале. Выпуск 3
Отмечу, что я собираюсь описать еще два способа. Один очень близок к данному, но удобнее, если исходных данных много и их можно объединить в смысловые группы. Это будет вариант 3.
Имеется и четвертый метод хранения исходных данных для программы. Он аналогичен тому, что применяется в системе Windows. Это INI-файлы. Эти файлы, как правило, имеют имя, совпадающее с именем программы их использующей, и расширение .INI.
Это обычные текстовые файлы. В таких файлах информация хранится в виде строк формата
Name=ValueДля работы с ними в Delphi имеется специальный класс TIniFile, а в этом классе - удобные методы для сохранения и поиска информации. Я напишу объект для работы с таким файлом на Паскале, но позднее ... :))
А сейчас числа, как и в предыдущем варианте, располагаются в определенном порядке, но перед каждым запишем, что это за величина
Нижняя граница =0.5 Правая: 100, Шаг = 5.1 outFileName= out.datДанные теперь записаны в виде строки и программе должно быть точно известно, что и на какой строке следует искать. Записывать данные в такой файл можно любым текстовым редактором. Информация перед значением параметра будет игнорироваться, так что можно писать все, что Вам нравится. Единственное условие: перед именем файла для вывода результатов должен стоять знак равенства "=".
Для упрощения анализа строки я написал процедуру для "выгрызания" чисел типа Real из строковой переменной:
procedure FindReal(Source: String; VAR Destign: Real;
VAR NBeg, CodeOp: Integer);
Эта процедура в строке символов Source, начиная с
позиции NBeg, пытается отыскать цепочку символов, которую
можно преобразовать в число типа Real. Если такую цепочку
удалось найти, то в переменную Destign заносится считанное
значение, а код завершения операции CodeOp будет равен нулю.
В противном случае CodeOp нулю не равен, а Destign сохранит
значение, установленное "по умолчанию". После завершения
работы процедуры NBeg указывает на первый символ, который не
анализировался.
Ниже я покажу пример использования, а сейчас код:
procedure FindReal(Source: String; VAR Destign: Real;
VAR NBeg, CodeOp: Integer);
CONST
BegOfNumb: SET OF CHAR = ['0'..'9']; {Этими символами начинается число}
NumbChars: SET OF CHAR = ['0'..'9','E','e','+','-','.']; {Эти символы могут
входить в состав числа. Любой символ, не входящий в группу,
воспринимается, как сигнал конца числа}
VAR
Buf_String: String; {сюда занесем найденную цепочку символов}
Buf_Real : Real; {в эту переменную преобразуем цепочку. Я
собираюсь использовать стандартную процедуру VAL,
а она портит число, если есть ошибки преобразования}
len : Integer; {длина анализируемой строки}
BEGIN
CodeOp:=-30; { установим код ошибки "не ноль" }
len:=LENGTH(Source); { запомнили длину анализируемой строки }
if (NBeg<=0) then EXIT; { таких значений NBeg быть не должно }
if NBeg>=len then EXIT; { Все, больше анализировать нечего }
Buf_String:='';
While (NOT (Source[NBeg] in BegOfNumb))
AND (NBeg < len) do INC(NBeg);
if NBeg=len then EXIT; { Все, дошли до конца строки, а цифр не нашли.
Выходим и код ошибки уже установлен }
{ Учтем, что числу может предшествовать знак, но только если это не
первый символ сторки. Этот символ включается в состав Buf_STRING }
if NBeg>1 then
if (Source[NBeg-1]='+') OR (Source[NBeg-1]='-')
then DEC(NBeg,1);
{ начало цепочки символов найдено, начинаем формировать Buf_STRING }
While (Source[NBeg] in NumbChars) AND (NBeg<=len) do
begin
Buf_String:=Buf_String + Source[NBeg];
INC(NBeg)
end;
{ Преобразование произведем с помощью процедуры VAL }
Val(Buf_String, Buf_Real, CodeOp);
{ Если преобразовать удалось (CodeOp=0 в этом случае), то результат
преобразования запишем в Destign }
if CodeOp=0 then Destign:=Buf_Real
END;
Для отыскания числа типа INTEGER можно написать
аналогичную процедуру, но проще считать число в буферную
переменную типа REAL, а затем преобразовать в число типа
INTEGER стандартной процедурой ROUND.
Пример использования такой процедуры дается ниже. Предполагается, что процедура описана в модуле MyIO003.pas. Его и все остальные файлы можно скачать в виде архива по адресу solv003.zip. Исходные данные содержатся в файле Solv003.dat. Он содержит одну строку текста, такую, какая показана выше.
Главная программа Solv003.pas:
program Solv003;
uses CRT, MyIO003;
function ReadData(AFileName: String;
var Left, Right, Step: Real;
var AName: String): Boolean;
var
ini: Text;
buf: String;
k, opCode: Integer;
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:= 'out003.dat';
ReadLn(ini, buf);
Close(ini); {Больше он нам нужен}
k:=1;
FindReal(buf, Left, k, opCode); if OpCode <> 0 then exit;
FindReal(buf, Right, k, opCode); if OpCode <> 0 then exit;
FindReal(buf, Step, k, opCode); if OpCode <> 0 then exit;
buf:=copy(buf, k, 255);
if pos('=', buf) = 0 then Exit; {Значение по умолчанию}
buf:=Copy(buf, pos('=', buf)+1, 255);
{Возможно, что содержатся лишние пробелы. Удалим ВСЕ!}
while pos(' ', buf) <> 0 do delete(buf, pos(' ', buf), 1);
if buf <> '' then AName:=buf; {Если что-то осталось}
end;
var
a, b, h, res: Real;
OutFileName: String;
OutFile: Text;
BEGIN
ClrScr;
if NOT ReadData('solv003.dat', a, b, h, OutFileName) then Halt(1);
WriteLn('>>>> ',a:10:2,' ',b:10:2,' ',h:10:2,' ',OutFileNAme);
Assign(OutFile, OutFileName);
{$I-} Rewrite(OutFile); {$I+}
if IOResult <> 0 then begin
WriteLn('Странно, но не могу создать файл: ', OutFileName); Halt(1)
end;
while a < b do begin
res:=sin(a);
WriteLn(a:10:2,' ',res:10:7); {Выводим на экран}
WriteLn(OutFile, a:10:2,' ',res:10:7); {Выводим в файл}
a:=a+h;
if a > b then a:=b
end;
Flush(OutFile);
Close(OutFile);
END.
Как видите, для чтения данных организована "специательная" процедура, выделенная курсивом. Больше ничего не скажу. Попробуйте использовать и задайте вопросы, если что непонятно
Свои вопросы и предложения присылайте Борису
Мы приглашаем Вас и Ваших друзей к сотрудничеству. Напишите, какая проблема Вас лично интересует - и мы постараемся помочь Вам. Поделитесь со всеми, если Вам удастся найти красивое решение. Присылайте свои программы, и если они хороши, то опубликуем их с обязательным указанием Вашего авторства.
По всем вопросам можно писать
либо в Гостевую книгу нашего сайта на www.turbopascal.tk, либо мне,
Рассылка поддерживается сайтом www.turbopascal.tk. При перепечатке ссылка на сайт обязательна