Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Delphi_part2

.pdf
Скачиваний:
9
Добавлен:
01.03.2016
Размер:
951.59 Кб
Скачать

позиции файла.

Количество считываемых символов для каждого параметра ввода зависит от типа этого параметра.

После считывания последовательности символов производится автоматическое преобразование последовательности символов в значение заданного типа. Следует заметить, что преобразования требуют даже данные типа String. Если преобразование не удается, фиксируется ошибка вводавывода, которая может быть обработана, например, с помощью конструкции try … except … end.

После завершения считывания информации файловая позиция устанавливается на первом непрочитанном символе.

Рассмотрим пример. Пусть текущая позиция файла перед выполнением инструкции read находится в положении, показанном на рисунке 12.1.

Текущая позиция файла

......Вам 17 лет, и у Вас еще все впереди.

Рисунок 12.1 – Образное представление текстового файла и места текущей позиции до операции чтения

После выполнения фрагмента кода:

var s1, s2: String[4]; i: integer; begin

read( f , s1, i, s2) ;

. . .

Значения переменных будут следующими: s1 = 'Вам ’

i = 17

s2 = ‘лет ’

Текущая позиция файла в результате считывания информации примет положение, показанное на рисунке 12.2.

101

Текущая позиция файла

......Вам 17 лет, и у Вас еще все впереди.

Рисунок 12.2 – Образное представление текстового файла и места текущей позиции после операции чтения read

Процедура readLn отличается от read только тем, что после чтения информации из файла для всех параметров ввода, переводит файловую позицию на новую строку, независимо от того, закончилась текущая строка или нет.

Если в процедуре readLn список параметров ввода пуст, то она просто переводит файловую позицию к началу следующей строки.

Например, если бы в предыдущем примере вместо процедуры read использовалась процедура readLn, то значения переменных s1, i, s1 не изменились бы, но положение текущей позиции приняло бы положение, показанное на рисунке 12.3.

Текущая позиция файла

......Вам 17 лет, и у Вас еще все впереди.

Рисунок 12.3 – Образное представление текстового файла и текущей позиции после операции readLn

12.1.6.1 Особенности чтения чисел из текстового файла

При обработке параметра ввода, которому соответствует числовой тип, процедура read или readLn выполняет следующие действия:

– пропускаются пробелы, символы табуляции, маркеры конца строк, которые считаются незначащими символами-разделителями;

считывается последовательность значащих символов до появления нового незначащего символа-разделителя (пробела, конца строки, символа табуляции);

выделенная таким образом подстрока рассматривается как символьное представление числа соответствующего типа и преобразуется в число;

полученное значение присваивается переменной, имя которой указано

в качестве параметра ввода.

Рассмотрим пример. Пусть текстовый файл ‘c:\numbers.txt’ содержит следующие строки:

102

24

15

32

45

28

 

56

71

34

Тогда, в результате выполнения последовательности инструкций:

AssignFile( f , c:\numbers.txt’);

Reset( f );

Read( f , a, b );

Readln( f , c , d );

Read( f , p );

Значения переменных будут следующими:

a = 24, b = 15, c = 32, d = 45, p = 56.

Число 28 будет пропущено, так как процедура readLn( f , c , d ) после считывания чисел 32 и 45 перевела файловую позицию в новую строку.

12.1.6.2 Особенности чтения данных типа String

При чтении из файла значения переменной типа String считывается столько символов, сколько указано в объявлении типа для данной переменной, но не больше, чем в текущей строке. Напомним, что если длина явно не задана, то она будет равна 255..

Рассмотрим пример. Пусть текстовый файл ‘c:\Family.txt’ содержит следующие строки:

Мать

Иванова

Мария

Николаевна

Отец

Иванов

Павел

Федорович

Сын

Иванов

Александр

Павлович

Тогда, в результате выполнения такой последовательности инструкций:

var f: TextFile; rodstvo: String[5]; name: String[8]; begin

assignFile( f , c:\Family.txt’); reset( f );

readln( f , rodstvo, name );

Значения переменных будут следующими: rodstvo = ‘Мать ‘

name = ‘Иванова ’

Если же последовательность инструкций будет такой:

var f: TextFile; rodstvo, name: String; begin

assignFile( f , c:\Family.txt’);

103

reset( f );

readln( f , rodstvo, name );

То значения переменных после чтения файла будут следующими: Rodstvo = ‘Мать Иванова Мария Николаевна‘

Name = ‘ ’.

В этом примере длина переменных явно не указана, поэтому для первой переменной были прочитаны все символы первой строки, а для второй переменной символов не хватило, поэтому она оказалась пустой. Переход на новую строку был выполнен при завершении процедуры.

Рассмотренные примеры свидетельствуют о том, что чтение строковых переменных из текстовых файлов с помощью процедуры read() требует тщательной подготовки текстового файла. Необходимо учитывать заявленную длину строки и именно столько позиций отводить для нее в текстовом файле. Иногда такой ввод называют вводом по шаблону. Это не очень удобно. Еще одно неудобство состоит в том, что реальные длины строковых переменных часто меньше заявленной длины строки, и при таком способе ввода они будут дополняться пробелами справа до заявленной длины. Поэтому значения переменных типа строка символов удобнее всего располагать в текстовом файле отдельными строками и считывать их с помощью процедуры readLn().

При выводе переменных или значений выражений типа строка символов в текстовый файл допускается использовать спецификатор длины строки в виде числа отделенного от переменной двоеточием. Это число указывает, сколько позиций в файле отводится для данной переменной. Если число меньше реальной длины строки, то строка обрезается. А если длина строки меньше, то строка слева добавляется пробелами. Например.

S:=’строка’;

Write(f1,s:3); // Получим ‘стр’

Write(f1,s:10); // Получим ‘ строка’

12.1.6.3 Особенности чтения и записи символов

Если переменная, читаемая из текстового файла, имеет символьный тип, то процедура read считывает очередной символ из файла и присваивает переменной его значение, независимо от этого значения, включая и символы перевода строки.

Аналогично происходит и запись символьных переменных.

В качестве примера можно рассмотреть процедуру посимвольного переписывания текстового файла f1 в текстовый файл f2.

var ch:Char; begin

reset(f1); rewrite(f2); while not eof(f1) do begin

104

read(f1,ch);

write(f2,ch);

end;

сloseFile(f1); сloseFile(f2);

12.1.7 Закрытие и удаление файлов

После окончания работы с файлом, его следует закрыть. Для закрытия используется процедура Close.

Обращение к этой процедуре выглядит так:

CloseFile ( <файловая переменная >);

При необходимости файл можно удалить. Для этого используется процедура Erase.

Обращение к этой процедуре выглядит так:

Erase ( <файловая переменная >);

12.2 ПЕРЕЧЕНЬ ОСНОВНЫХ ПРОЦЕДУР ДЛЯ РАБОТЫ С ТЕКСТОВЫМИ ФАЙЛАМИ

Таблица 12.1 – Основные процедуры, обеспечивающие работу с файлами

Назначение операции

Синтаксис операции

 

TextFile

Описание типа файла

 

AssignFile( <файловая переменная>, <имя файла> )

Определение имени

 

Rewrite( <файловая переменная > )

Создание для записи

 

Reset( <файловая переменная > )

Установка в начало

для чтения

 

Установка в конец для

Append( <файловая переменная > )

добавления

 

Закрыть файл

CloseFile ( <файловая переменная > )

 

Erase( <файловая переменная > )

Удалить файл

 

Write(<файловая переменная >, <список выражений>)

Записать в файл

 

WriteLn(<файл. переменная >, <список выражений>)

Читать из текущей

Read(<файловая переменная >, <список переменных >

файловой позиции

ReadLn(<файлов. переменная >, <список переменных >

Конец строки

EoLn( <файловая переменная > )

 

Eof( <файловая переменная > )

Конец файла

 

 

105

12.3 ОБЩАЯ СХЕМА РАБОТЫ С ТЕКСТОВЫМ ФАЙЛОМ

Описание файловой переменной:

Var f : TextFile;

Связывание файловой переменной с именем файла:

AssignFile(f, имя файла);

Открытие для

Создание нового файла для

Открытие для

чтения

записи (старый файл

добавления в

Reset(f)

уничтожается)

существующий файл)

Текущая позиция

Rewrite(f)

Append(f)

устанавливается в

Текущая позиция

Текущая позиция

начало файла

устанавливается в начало

устанавливается в

 

файла

конец файла

 

 

 

Чтение из файла

Read(f,список параметров); ReadLn(f,список параметров);

Запись в файл

Write(f,список параметров); Writeln(f,список параметров);

Закрытие файла

CloseFile(f)

12.3.1 Примеры работы с текстовыми файлами

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

Поэтому основные задачи, при работе с текстовым фалом – это задачи ввода и вывода информации.

Рассмотрим некоторые примеры проекта, который можно найти в папке

ProjectToLection\ToLection20.

12.3.1.1 Пример ввода-вывода при решении простейшей задачи

В качестве примера возьмем задачу расчета по простейшей формуле y=(a+b)/c.

Предположим, что исходные данные находятся в текстовом файле, который связан с файловой переменной f1. Результат будем выводить в текстовый файл, связанный с переменной f2 .

106

Процедура расчета будет выглядеть так.

//Расчет по формуле

procedure TForm1.btnCalcFormulaClick(Sender: TObject); var a,b,c,y:real ;

begin

Reset(f1); Rewrite(f2); read(f1,a,b,c); y:=(a+b)/c;

writeln(f2,'a=',a:1:2,' b=',b:1:2,' c=',c:1:2); writeln(f2,' y=',y:1:2);

closeFile(f1);

closeFile(f2);

end;

Пусть содержимое файла с исходными данными будет, например, таким. 2 3 0.5

Тогда в файле результатов мы получим следующую информацию a=2.00 b=3.00 c=0.50

y=10.00

12.3.1.2 Пример добавления данных из одного файла к другому

Ниже приведен фрагмент процедуры.

var s:String; begin

Reset(f1); Append(f2); while not eof(f1) do begin readln(f1,s);

writeln(f2,s);

end;

CloseFile(f1);

CloseFile(f2);

107

12.3.1.3 Пример чтение из файла в поле Memo

...

var buf: String; begin

AssignFile(f, ‘Primer.txt’); try

reset(f); //Открыть для чтения except

showMessage(‘Ошибка доступа к файлу’);

exit;

 

 

end;

 

 

// Цикл чтение из файла

 

 

while not eof(f) do

 

 

begin

 

 

Readln(f, buf);

// прочитать строку из файла в переменную buf

Memo1.Lines.Add(buf);

// добавить строку, содержащуюся

 

 

// в переменной buf к строка поля Memo1

end;

closeFile(f);

end;

12.3.1.4 Пример ввода-вывода при работе с массивом

При вводе числовых массивов можно использовать процедуру read() для считывания элементов массива. Элементы могут располагаться в файле произвольно. Считывание производится, пока не будет достигнут конец файла.

При занесении исходных данных для массива в текстовый файл не следует после последнего числа вводить символ перевода строки, иначе будет считан дополнительный, лишний ноль.

Ниже приведен пример ввода массива из текстового файла, его обработка и вывод массива результатов.

Считывается столько элементов массива, сколько их в файле. Расположение элементов массива в файле не имеет значения

Обработка заключается в накоплении значений элементов массива. Массив, полученный в результате обработки, выводится столбиком, то

есть каждый элемент отдельной строкой.

108

//Работа с массивом

procedure TForm1.btnArrayClick(Sender: TObject); var a:array[1..100] of integer; i, count: integer;

begin

Reset(f1); Rewrite(f2);

//Ввод массива count:=0;

while not eof(f1) do begin count:=count+1; read(f1,a[count]);

end;

//Обработка массива

for i:=2 to count do a[i]:=a[i]+a[i-1];

//Вывод массива

for i:=1 to count do writeln(f2,a[i]); closeFile(f1);

closeFile(f2);

end;

12.3.1.5 Пример ввода-вывода при работе с матрицей

Особенность считывания матриц из текстового файла состоит в том, что необходимо распознавать строки. Для решения этой задачи можно использовать цикл ввода элементов строки с помощью функции read(). Элементы строки вводятся пока значение функцию Eoln() равно false. Количество столбцов матрицы будет равно количеству элементов в строке.

Очевидно, что данные в текстовом файле должны быть расположены в виде таблицы. Произвол здесь уже не допустим.

При выводе матрицы следует позаботиться о переводе строки после вывода каждой строки матрицы. Кроме того, следует использовать спецификаторы длины достаточного размера, чтобы числа в строках не сливались.

Ниже приводится процедура считывания матрицы из текстового файла и вывода ее в текстовый файл.

//Работа с матрицей и текстовым файлом procedure TForm1.btnMatrixClick(Sender: TObject);

var m: array[1..10, 1..10] of integer; i, j, countRow, countCol: integer; begin

109

reset(f1); rewrite(f2);

//Вводим первую строку и определяем число столбцов матрицы countCol:=0;

while not eoln(f1) do begin countCol := countCol + 1; read(f1, m[1, countCol]);

end;

readln(f1); //переход к новой строке

if countCol > 0 then countRow:=1 else exit;

//Вводим оставшиеся строки while not eof(f1) do begin countRow:=countRow+1;

j:=0;

while not eoln(f1) do begin j:=j+1;

read(f1, m[countRow, j]); end;

readln(f1); //переход к новой строке end;

//Вывод матрицы

for i:=1 to countRow do begin

for j:=1 to countCol do write(f2, m[i,j]:6); writeln(f2);//переход к новой строке

end;

closeFile(f1);

closeFile(f2);

end;

12.3.1.6 Пример ввода-вывода при работе с записями

Особенность считывания записей из текстового файла состоит в том, что записи могут иметь поля разного типа. Если есть поля типа строка символов, то их лучше располагать отдельными строками. Не следует в одной строке располагать данные разных записей.

Вывод записей следует организовать так, чтобы было удобно анализировать информацию.

110

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]