Объявление файловой переменной для текстового файла 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Объявление файловой переменной для текстового файла



Описание файловой переменной для текстового файла в общем виде выглядит так:

<имя файловой переменной>: TextFile;

Пример:

var f: TextFile; // объявлена файловая переменная f типа TextFile

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

 

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

 

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

Пример:

var f: TextFile;

Begin

AssignFile(f, ‘a:\result.txt’);

Или

var f: TextFile; fName: String;

Begin

fName:= ‘Pogoda.txt’;

AssignFile(f, fName);

...

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

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

Так же как и в случае типизированных файлов, исключительные ситуации, возникающие при открытии файла можно обрабатывать с помощью конструкции try … except … end, или с помощью функции IOResult.

Существует три способа открытия текстового файла.

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

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

Реализуется такой способ открытия файла процедурой Rewrite.

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

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

Ниже приведен пример вызова процедуры Rewrite:

Rewrite (f1);

12.1.3.2 Открытие файла для чтения

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

Реализуется такой способ открытия файла процедурой Reset.

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

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

Ниже приведен пример вызова процедуры Reset:

Reset (f1);

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

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

12.1.3.3 Открытие файла для дополнения

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

Реализуется такой способ открытия файла процедурой Append.

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

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

Ниже приведен пример вызова процедуры Append:

Append (f1);

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

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

При работе с текстовым файлом, так же как и при работе с типизированным, используется понятие «текущая позиция файла». В текстовом файле под «текущей позицией файла» подразумевается то место в файле, откуда будет продолжаться чтение, или откуда начнется запись при очередном обращении к файлу. Фактически, это номер очередного байта в файле, но в Object Pascal нет доступа к этой позиции текстового файла.

Записи данных в файл.

Как было сказано выше, запись данных в текстовый файл возможна в случае открытия файла с помощью процедур Rewrite или Append. Напомним, что при открытии файла с помощью процедуры Rewrite текущая позиция файла находится в начале файла, а при открытии с помощью процедуры Append текущая позиция находится в конце файла.

Запись данных в текстовый файл осуществляется при помощи инструкций write и writeln.

В общем виде запись этих инструкций выглядит так:

write(f, a1, a2.. an);

writeLn(f, a1, a2.. an);

В этой записи f – файловая переменная; a1, a2.. an – это список параметров вывода. Параметром вывода может быть переменная одного из простых типов, константа или выражение. Каждый параметр может иметь спецификаторы вывода, которые определяют количество позиций выделяемых в файле для выводимого параметра и способ вывода значений параметров. Спецификаторы в виде целых числе записываются после параметра через вертикальные двоеточия.

В общем случае параметр вывода со спецификаторами может иметь такую форму:

<выводимое выражение>[: <minWidth>[:<decPlaces>]], где minWidth, если присутствует, то указывает минимальную ширину поля вывода, а decPlaces используется для вывода значений вещественных чисел и задает количество знаков после запятой.

Использование спецификаторов в процедуре write подобно использованию спецификаторов в функции format.

Рассмотрим простейший пример:

v:= 12,456

write(f, v: 6: 2);

Эта инструкция запишет значение переменной v в текстовый файл в таком виде: 12,45 – т.е. для строкового представления этого числа отведется 6 позиций и для десятичных знаков после запятой – 2 позиции.

Ниже приводится еще один пример использования процедуры write со спецификаторами для вывода значения числа π, его квадрата и корня из этого числа.

write (t,'-пи =',-pi,', его квадрат =',sqr(pi):6:2,', и корень =',sqrt(pi):3);

Результатом выполнения этой процедуры будет строка символов, приведенная ниже.

-пи =-3.14159265358979E+0000, его квадрат = 9.87, и корень = 1.8E+0000

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

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

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

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

Различие между инструкциями write и writeLn состоит в том, что инструкция writeLn после занесения в файл всех значений, указанных в списке параметров, записывает в файл символ перехода на новую строку - EOLN (новая строка).

При вызове процедуры writeLn список параметров может быть пустым. В этом случае в файл передается пустая строка

Фрагмент кода, в котором осуществляется запись содержимого поля Memo1 в файл с именем ‘Primer.txt’ в режиме перезаписи, с использованием процедуры writeLn представлен ниже.

Begin

assignFile(f, ‘Primer.txt’);

rewrite(f); // открыть для перезаписи

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

for i:=0 to Memo1.Lines.Count do writeln(f, Memo1.Lines[i]);

closeFile(f);

End;

После выполнения этого фрагмента кода в текстовом файле появится копия содержимого компонента Memo.

Чтение данных из файла

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

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

В общем виде эти инструкции будут иметь вид:

read (f, a1, a2, …, an);

readLn (f, a1, a2, …, an);

В этой записи f – файловая переменная; a1, a2.. an – это список параметров ввода. Параметром ввода может быть только переменная одного из простых типов (Char, String, Integer, Real).

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

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

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

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

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

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

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

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

Begin

read(f, s1, i, s2);

...

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

s1 = 'Вам ’

i = 17

s2 = ‘лет ’

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

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

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

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

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

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

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

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

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

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

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

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

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

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’);

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

read(f1,ch);

write(f2,ch);

end;

сloseFile(f1);

сloseFile(f2);

 

 

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

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

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

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

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

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

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

12.2 Перечень основных процедур для работы с текстовыми файлами

Таблица 11.1 – Основные процедуры, обеспечивающие работу с файлами
Назначение операции Синтаксис операции
Описание типа файла TextFile
Определение имени AssignFile (<файловая переменная>, <имя файла>)
Создание (очистка) для записи Rewrite (<файловая переменная >)
Установка в начало для чтения Reset(<файловая переменная >)
Установка в конец для добавления Append(<файловая переменная >)
Закрыть файл CloseFile (<файловая переменная >)
Удалить файл Erase(<файловая переменная >)
Размер файла FileSize(<файловая переменная >)
Номер текущей записи FilePos(<файловая переменная >)
Перейти к записи Seek(<файловая переменная >, <номер записи>)
Записать в текущую файловую позицию Write(<файловая переменная >, <переменная соотв. типа>)
Читать из текущей файловой позиции Read(<файловая переменная >, <переменная соотв. типа>
Конец строки EoLn(<файловая переменная >)
Конец файла Eof(<файловая переменная >)

 

12.3 Общая схема работы с текстовым файлом

 

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

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

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

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

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

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

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

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

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

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);

 

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 () для считывания элементов массива. Элементы могут располагаться в файле произвольно. Считывание производится, пока не будет достигнут конец файла.

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

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

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

Обработка заключается в накоплении значений элементов массива.

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

 

 

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

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

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 exi t;

//Вводим оставшиеся строки

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 Пример ввода-вывода при работе с записями

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

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

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

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

Борщ К.Е.

3 4 5 1 2

Бублик К.П.

1 2 3 4 5

Вареник Г.Т.

3 4 5 5 5

Нетудикидайченко Н.К.

1 2 1 2 1

 

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

//Обработка записей

procedure TForm1.btnRecordClick(Sender: TObject);

Type

Trec = record

fio:string[10];

marks: array [1..5] of integer;

end;

var a: array [1..100] of TRec; count, i, j:integer;

Begin

Reset(f1);

//Считывание массива записей

count:= 0;

while not eof(f1) do begin

count:=count + 1;

readln(f1,a[count].fio);

for j:= 1 to 5 do read(f1,a[count].marks[j]);

readln(f1);

end;

closeFile(f1);

//Вывод массива записей в текстовый файл

Rewrite(f2);

for i:= 1 to count do begin

write(f2, a[i].fio:10);

for j:=1 to 5 do write(f2, a[i].marks[j]:2);

writeln(f2);

end;

closeFile(f2);

end;

Результаты работы программы будут такими.

Борщ К.Е. 3 4 5 1 2

Туз К.П. 1 2 3 4 5

Вареник Г. 3 4 5 5 5

Нетудикида 1 2 1 2 1

 

12.4 Задания для самостоятельной работы

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

Для удобства просмотра исходных данных и результатов обработки следует использовать компоненты TMemo.

Образцом для выполнения задания может служить проект из папки kid\pub\subject\1_kurs\ projectToLection\.To_lection_20.

Следует решить такие задачи в соответствии со своими вариантами:

– Табулирование значений функции аналогично работе №6.

– Получение нового массива по варианту работы №7.

– Сортировку массива по варианту работы №8.

– Задачи на перестановку элементов матрицы по варианту работы №9.

– Выборка записей по варианту работы №10

12.5 Содержание отчета

– Наименование работы.

– Цель работы.

– Краткая характеристика текстовых файлов.

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

– Интерфейс созданного проекта.

– Текст модуля проекта с пояснениями в виде комментариев.

– Результаты тестирования проекта в виде копий формы с результатами.

– Выводы.

Контрольные вопросы

– Характеристики текстовых файлов.

– Процедуры, используемые при открытии файла.

– Анализ исключительных ситуаций, возникающих при открытии файла.

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

– Закрытие и удаление файла.

– Особенности чтения чисел из текстовых файлов.

– Особенности вывода чисел в текстовые файлы.

– Особенности чтения строк из текстовых файлов.

– Особенности вывода строк в текстовые файлы.

– Особенности хранения записей в текстовых файлах

– Ввод массивов из текстовых файлов.

– Ввод матриц из текстовых файлов.

– Объяснение текстов подпрограмм модуля и связей их с событиями и другими подпрограммами.

– Написать процедуру для реализации запроса к файлу по указанию преподавателя.

– Написать процедуру для реализации выбора некоторых данных из исходного файла в новый файл, по заданию преподавателя.

Рекомендованая литература

1. Культин Н. Delphi 6. Программирование на Object Pascal. – СПб.:БХВ-Петербург,2002.

2. Ставровский А.Б. Турбо Pascal 7.0/ Учебник. – К.: BHV, 2000.

 



Поделиться:


Последнее изменение этой страницы: 2017-02-07; просмотров: 481; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.221.41.214 (0.25 с.)