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

Delphi_part2

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

end;

11.3.8.3 Добавление записи в отсортированный файл

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

//Добавить запись в отсортированный файл procedure addToSortFile(var f:TAttFile; r:TAttRec);

var pos:integer; rf:TAttRec; begin

//Начинаем с конца файла pos:= fileSize(f);

repeat //Повторяем пока не найдем, куда вставить pos:=pos-1;

if pos = -1 then break; // значит надо вставлять в начало //Сдвигаем очередную запись на одну позицию вниз seek(f, pos);

read(f, rf); write(f, rf);

until rf.name < r.name;

// Нашли место для вставки seek(f,pos+1);

write(f,r);

end;

11.3.8.4 Удаление записи из отсортированного файла

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

//Удалить запись из отсортированного файла procedure delFromSortFile(var f: TAttFile; fam: TName);

91

var pos: integer; rf: TAttRec; begin

//Ищем позицию записи с заданной фамилией pos := findPosInSortFile(fam, f);

if pos < 0 then begin showMessage(fam+' не найдено'); exit;

end;

//Сдвигаем все записи начиная со следующей за найденной while pos < fileSize(f) - 1 do begin

pos:=pos + 1; seek(f, pos); read(f, rf); seek(f, pos-1); write(f, rf);

end;

//Обрезаем последнюю запись

seek(f, fileSize(f) - 1); truncate(f);

end;

11.3.9 Процедуры реализации пунктов меню sortMenu

11.3.9.1 Реализация пункта меню «Сортировка файла по фамилиям»

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

//Вызов сортировки по фамилиям

procedure TfrmAtt.mnuSortFamClick(Sender: TObject); var f:TAttFile;

begin openAttFile(f); sortAttFile(f);

showFileInGrid(f, StringGrid3); CloseFile(f);

92

end;

11.3.9.2 Реализация пункта меню «Поиск студента по фамилии»

Эта процедура связана с пунктом меню «Поиск студента по фамилии».

// Поиск студента по фамилии

procedure TfrmAtt.mnuFindInSortClick(Sender: TObject); var f:TAttFile; pos: integer; r: TAttRec; fam: TName;

begin

fam:=inputBox('Поиск зарплаты по фамилии','Введите фамилию',''); openAttFile(f);

sortAttFile(f);

pos := findPosInSortFile(fam,f);

if pos < 0 then showMessage(fam+' не найдено') else begin

seek(f,pos);

read(f,r);

showMessage('Результаты аттестации ' + fam + #13 + 'Ср.балл = ' + floatToStr(r.ball) + #13 + 'Количество неуд = ' + intToStr(r.neud));

end;

CloseFile(f);

end;

11.3.9.3 Реализация пункта меню «Добавление в упорядоченный файл из StringGrid1»

Эта процедура связана с пунктом меню «Добавление в упорядоченный файл из StringGrid1»

//Добавление в упорядоченный файл из StringGrid1 procedure TfrmAtt.mnuAddToSortClick(Sender: TObject);

var f:TAttFile; r:TAttRec; i: integer; begin

openAttFile(f);

sortAttFile(f);

// Идем по строкам StringGrid1

93

for i := 1 to StringGrid1.RowCount-1 do begin

//Формируем запись из i-й строки StringGrid1 r.Name := StringGrid1.Cells[0,i];

r.ball := strToFloat(StringGrid1.Cells[1,i]); r.neud := strToInt(StringGrid1.Cells[2,i]);

//Добавляем к файлу

addToSortFile(f, r); end;

showFileInGrid(f,StringGrid3);

CloseFile(f);

end;

11.3.9.4 Реализация пункта меню «Удаление записи из отсортированного файла»

//Удаление записи из отсортированного файла procedure TfrmAtt.mnuDelInSortClick(Sender: TObject);

var fam:TName; f:TAttFile; begin

fam:=inputBox('Удаление записи из файла','Введите фамилию',''); openAttFile(f);

sortAttFile(f);

delFromSortFile(f,fam);

showFileInGrid(f,StringGrid3);

CloseFile(f);

end;

11.4 ЗАДАНИЕ ДЛЯ САМОСТОЯТЕЛЬНОЙ РАБОТЫ

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

Создаваемый проект должен обеспечить:

Отображение записей файла в StringGrid.

Добавление группы записей из StringGrid к файлу.

Сохранение файла под другим именем

94

Поиск записи по значению одного из полей.

Удаление из файла записи, соответствующей заданному значению одного из полей.

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

Сортировку файла по какому-нибудь признаку.

Поиск записи в упорядоченном файле.

Вставку записи в упорядоченный файл.

Удаление записи из упорядоченного файла.

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

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

11.5 СОДЕРЖАНИЕ ОТЧЕТА

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

Цель работы.

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

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

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

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

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

Выводы.

КОНТРОЛЬНЫЕ ВОПРОСЫ

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

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

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

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

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

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

Написать цикл последовательной обработки всех записей файла.

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

Сортировка файла одним из трех методов (пузырек, выбор, вставка).

Поиск записи в упорядоченном файле.

Удаление записи в упорядоченном файле.

Добавление записи к упорядоченному файлу.

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

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

95

12 ЛАБОРАТОРНАЯ РАБОТА № 12. РАБОТА С ТЕКСТОВЫМИ ФАЙЛАМИ

Цели работы:

Познакомиться с понятием текстового файла и особенностями хранения информации в таких файлах.

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

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

12.1 КРАТКИЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ

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

Вконце текстового файла находится признак конца файла.

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

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

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

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

Пример:

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

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

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

96

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

Пример:

var f : TextFile; begin

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

Или

var f : TextFile; fName : String; begin

fName := ‘Pogoda.txt’; AssignFile( f , fName);

. . .

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

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

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

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

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

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

Реализуется такой способ открытия файла процедурой Rewrite. Обращение к этой процедуре выглядит так:

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

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

Rewrite (f1) ;

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

Второй способ открытия файла, предполагает, что файл существует, и

97

информация из него будет считываться.

Реализуется такой способ открытия файла процедурой Reset. Обращение к этой процедуре выглядит так:

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

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

Reset (f1) ;

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

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

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

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

Реализуется такой способ открытия файла процедурой Append. Обращение к этой процедуре выглядит так:

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

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

Append (f1) ;

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

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

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

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

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

98

что при открытии файла с помощью процедуры 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

 

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

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

99

типизированный файл.

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

При выводе в текстовый файл параметров может быть сколько угодно и каждый из них перед выводом вычисляется и преобразуется в текст. Преобразование производится так как, например, для вещественных чисел вызывается функция 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.

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

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

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

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

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

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

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

100

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