2. Что такое

advertisement
Лабораторная работа № 7
Обработка файлов средствами языка Turbo Pascal
7.1. Цель работы
Освоение
методики
проектирования
Pascal-программ
с
использованием операций с файлами.
7.2. Задание на лабораторную работу
Разработать
две
программы,
выполняющие
заданные
последовательности действий над данными определенного типа с
использованием файлов в соответствии с вариантом задания.
7.3. Требования к программе
Программа должна выполнять:
–
вывод
сообщения
о
разработчике
и
о
назначении
программы;
– ввод данных в режиме диалога.
Сохранение данных в файле и чтение данных из файла
организовать как процедуру или функцию.
Выполнить контроль ошибок при открытии файлов.
7.4. Порядок выполнения работы
1. Получить вариант задания (п. 7.7, таблица 7.1).
2. Изучить процедуры и функции, используемые для работы с
файлами, и необходимые для выполнения данной лабораторной
работы (п. 7.5).
3. Разработать алгоритм подготовки и обработки данных на
основе заданных операций.
4. Подготовить текст программы и отладить программу с
использованием среды Turbo Pascal; см. пример п. 7.6.
5. Устно ответить на контрольные вопросы (п. 7.9).
6. Оформить отчет (см. п. 1.10).
7.5. Справки по файловым процедурам и функциям
Файл
–
поименованная
область
памяти
на
внешнем
запоминающем устройстве, предназначенная для хранения данных.
Файл можно представить как список значений одного и того
же (базового) типа; количество значений в программе не
ограничивается.
Все
элементы
файла
считаются
пронумерованными;
начальный элемент имеет нулевой номер.
Как правило, действия с файлом (чтение из файла, запись в
файл) производятся поэлементно; в действиях участвует тот
элемент файла,
который обозначается текущим указателем.
Текущий указатель можно понимать как скрытую переменную (то
есть неявно описанную вместе с файловой переменной), которая
обозначает («указывает») на некоторый конкретный элемент файла.
При
выполнении
операций
текущий
указатель
может
автоматически (без явного указания в программе) перемещаться.
7.5.1. Описание файловых переменных
Для работы с файлами в программе должны быть определены
переменные файловых типов, которые считаются представителями
файлов в Pascal-программе.
Переменные файлового типа определяются по следующему
правилу:
<Имя переменной> : file of <базовый тип>;
где «базовый тип» – любой допустимый в Turbo Pascal тип, кроме
файлового типа.
Примеры описаний файловых типов и переменных:
Type Person = record
Name : string[40];
Tarif : Longint
end;
FP = file of Person;
Var F1, F2 : FP;
{F1, F2 - файловые переменные
для представления
в программе файлов, которые могут содержать записи
типа Person}
{переменная
для
работы
с
Table : file of String[80]; {переменная
для
работы
с
Symb_F : file of char;
файлами, которые могут
содержать символы}
файлами, которые
могут содержать символы}
InputData : file of real;
F : file of integer;
7.5.2. Установочные и завершающие операции с файлами
В эту группу входят четыре операции, реализованные в виде
стандартных процедур со следующими именами: Assign, Reset,
Rewrite, Flush, Close.
Процедура Assign предназначена для установления связи
между конкретным физическим файлом на магнитном носителе и
переменной
файлового
типа,
которая
будет
являться
представителем этого файла в программе.
Правило обращения к процедуре Assign:
Assign (F, S);
F – имя файловой переменной,
S – строковое выражение, образующее имя файла по
правилам, принятым в операционной системе MS-DOS (может
включать в себя обозначение дисковода, цепочку каталогов и имя
файла).
Примеры:
Assign (F, ‘D:\MYDIR\MyFile.dta’ );
После выполнения данного вызова файловая переменная F
будет связана с дисковым файлом MyFile.dta, расположенным в
каталоге MYDIR из корневого каталога диска D).
.................
S:=’RESULT.DAT’;
Assign (F1, S);
.................
write(‘Введите имя файла для сохранения данных:’);
readln(S); Assign (F2, S);
.................
Процедура Reset(F) предназначена для открытия файлов для
чтения. При этом файловая переменная F должна быть уже связана
с конкретным дисковым файлом с помощью процедуры Assign.
Под открытием в данном случае понимается поиск файла на
внешнем носителе, образование специальных системных буферов
для обменов с ним и установка текущего указателя файла на его
начало (то есть на нулевой элемент).
Процедура Reset(F) предполагает, что открываемый дисковый
файл уже существует, в противном случае возникает ошибка.
Процедура Rewrite(F) предназначена для открытия файлов для
записи. При этом файловая переменная F должна быть уже связана
с конкретным дисковым файлом с помощью процедуры Assign.
Процедура Rewrite допускает, что открываемый файл может
еще не существовать; в этом случае она создает заданный файл.
Если же файл существует, то Rewrite очищает его.
Процедура Flush(F) используется для завершения обменов с
файлом без его закрытия. Обмены с файлами всегда реализуются
через некоторый буфер в оперативной памяти, поэтому в процессе
записи в файл последние записываемые элементы могут еще
находиться («застрять») в буфере. Процедура Flush вызывает
принудительный сброс этих элементов в файл.
Процедура Close(F) завершает действия с файлом. При этом
ликвидируются внутренние буферы, образованные при открытии
файла, оставшиеся в буфере данные сохраняются в файле.
7.5.3. Операции ввода-вывода
Операции ввода-вывода (чтения из файла и записи в файл)
реализуются с помощью процедур: Read, Write.
Правила записи операторов:
Read(F, A, B, C,...);
Write(F1, X, Y, Z, ...);
F, F1 – имена файловых переменных, к которым были
применены операции открытия Reset и Rewrite соответственно,
A, B, C – переменные, типы которых совпадают с базовым
типом файловой переменной F,
X, Y, Z – выражения, типы которых совпадают с базовым
типом файловой переменной F1.
Примеры:
Read(F, A);
{чтение значения одного элемента файла}
Read(F, B, C); {последовательное чтение значений двух
элементов}
Read(F, M[i]); {чтение
значения
одного
элемента
и
присвоение прочитанного значения элементу массива (запись в
массив)}
Write(F1, X);
{запись значения одной переменной в файл}
Write(F1, X, Y);
{последовательная запись значений двух
переменных в файл}
Write(F1, M[i]);
{запись значения i-го элемента массива
в файл}
Write(F1, X, X*X, X+Y, X/(Y-Z));
{последовательная
запись в файл значений указанных выражений}
................
Выполнение
процедуры
Read
происходит
следующим
образом. Начиная с текущей позиции указателя файла будут
последовательно читаться значения, содержащиеся в файле.
Каждое прочитанное значение будет присваиваться очередной
переменной из тех, которые указаны в вызове процедуры. После
чтения очередного значения указатель файла будет смещаться на
следующую позицию. Если в процессе выполнения процедуры
Read текущий указатель файла будет установлен на позицию, не
содержащую информации (то есть будет достигнут конец файла),
то
чтение
будет
преждевременно,
прекращено,
и
возникнет
процедура
ситуация
Read
завершится
‘конец
файла».
Возникновение этой ситуации можно проверить с помощью
встроенной функции EOF.
При выполнении процедуры Write значение очередного
выражения будет помещено в файл в место, отмеченное текущим
указателем. После этого текущий указатель будет передвинут на
одну позицию и действия повторятся для следующего выражения
из списка параметров вызова процедуры Write.
7.5.4. Операции перемещения по файлу, определение
параметров файла
Процедура Seek(F, N) позволяет явно изменить значение
текущего указателя, установив его на элемент файла с заданным
номером (N), где F – переменная файлового типа, N – переменная
типа Longint.
После выполнения процедуры Seek дальнейшие операции
чтения или записи будут проводиться начиная с установленной
позиции указателя.
Функция FileSize(F) определяет число элементов файла.
Функция FilePos(F) определяет номер элемента, на который
установлен текущий указатель.
Примеры использования:
Seek (F, FilePos (F)+1)
{пропуск одного элемента}
Seek (F, FileSize (F)) {установка
текущего
указателя
непосредственно за последним элементом файла; это может
служить исходной позицией для добавления злементов в конец
файла}
Функция EOF(F) возвращает логическое значение true, если
достигнут признак конца файла, или false в противном случае.
Например, если файл использовался для чтения, то возникновение
ситуации «конец файла» (и, соответственно, значение true,
возвращаемое функцией EOF) означает, что все элементы файла
прочитаны.
Процедура Truncate(F) используется для удаления части
файла, начиная от текущей позиции указателя до окончания файла.
7.5.5. Обработка ошибок ввода-вывода
В программе на языке Turbo Pascal установлены следующие
правила обработки ошибочных ситуаций, связанных с вводомвыводом. По умолчанию при выполнении любой такой операции
автоматически производится проверка на возникновение ошибки.
При обнаружении ошибки выполнение программы прекращается, а
на экран дисплея выводится краткое диагностическое сообщение,
содержащее условный номер ошибки.
Имеется возможность предусмотреть собственную реакцию на
ошибочные ситуации в самой программе. Для этого необходимо в
начале
«опасного»
фрагмента
программы
отключить
автоматическую проверку на возникновение ошибки. Это делается
внесением
директивы
компилятора
{$1-}.
В
этом
случае
возникновение ошибки при выполнении программы не будет
приводить к немедленному ее завершению; вместо этого код
ошибки (отличный от нуля) будет сохранен системой. Посредством
стандартной функции IoResult без параметров можно получить этот
код и построить дальнейшие действия в зависимости от его
значения, например, вывести краткое сообщение об ошибке (без
указания причины ошибки):
..........
Assign (F, ‘c:\myfile’ );
{$I-}
{ отключение автоматического контроля }
Reset (F);
($I+)
{ включение автоматического контроля }
if loResult <> 0 then { возникла ошибка! }
begin
Writeln(‘Ошибка при открытии файла для чтения’);
Writeln(‘Работа будет закончена.’);
Writeln;
Writeln(‘Нажмите Enter ...’);
Readln;
Exit
{Выход из процедуры}
end;
При использовании функции IoResult нужно знать, что если
отключен режим автоматического контроля ({$I-}), то после
возникновения ошибки все последующие операции с любым
файлом будут игнорироваться, пока не произойдет обращение к
функции IoResult. Поэтому необходимо выполнить вызов функции
и анализ кода ошибки сразу после выполнения операции, связанной
с файлом.
При
необходимости
можно
провести
более
детальный
(расширенный) анализ кода ошибки, например:
Assign (F, ‘ с: \myfile ‘ );
{ отключаем автоматический контроль }
{$1-}
Reset (F);
Code :=IoResult;
{ получили код результата }
if Code <> 0 then
begin
{ возникла ошибка! }
Write(‘ Ошибка при открытии файла: ‘);
саsе Code of
1 : Writeln (‘Файл не найден’);
3 : Writeln (‘Маршрут не найден’);
4 : Writeln (‘Слишком много открытых файлов’);
5 : Writeln (‘Доступ к файлу запрещен’);
12 : Writeln (‘Некорректный код доступа к файлам’)
else
Writeln(‘Неизвестный код ошибки’);
end
end;
{$I+) ( включаем автоматический контроль }
................
7.5.6. Текстовые файлы
Содержимое
текстового
последовательность
файла
символьных
рассматривается
строк
переменной
как
длины,
разделенных специальной комбинацией кодов, «конец строки» (13
или 0Dh), «перевод строки» (10 или 0Ah). Текстовый файл
завершается специальным кодом «конец файла» (26 или 1Ah).
Представителем
текстового
файла
в
Pascal-программе
является переменная файлового типа, которая должна быть описана
с указанием стандартного типа text; например,
var MyText : text;
Для
текстовых
файлов
применимы
вышеопределенные
начальные и завершающие операции (Assign, Reset, Rewrite, Flush,
Close).
Текстовый файл может быть открыт для дополнения с
помощью процедуры Append (F); эта процедура открывает файл
для записи, но не очищает его, а устанавливает текущий указатель
файла за последней записью.
Для записи в текстовый файл и чтения из него используются
процедуры ReadLn и WriteLn. Эти процедуры осуществляют те же
действия, что и соответствующие процедуры Read и Write, но после
операций чтения и записи производят переход к следующей строке
текстового файла.
Для контроля за окончанием текстового файла можно
использовать функцию EOF.
Функция SeekEoLn(F) производит поиск конца текущей
строки. Она пропускает все символы-разделители значений в
строке (пробелы и табуляции) и устанавливает текущий указатель
файла либо на конце строки (и тогда возвращает true), либо на
первом значащем символе.
Функция SeekEoF(F) осуществляет поиск конца файла и
действует аналогично функции SeekEoLn, но кроме символовразделителей она пропускает символы концов строк (то есть
переходит со строки на строку) в поисках кода конца файла. Если
код 1Ah найден, то функция возвращает true, в противном случае –
false.
7.6. Пример структуры программы
program file_operation;
{Программа
для
работы
со
списком сотрудников}
uses crt;
type
zap=record
{Определение записи с полями «фамилия» -
name, «тарифная ставка» - tarif}
name:string[15];
tarif:LongInt
end;
var
F1: file of zap;
s : zap;
c : char;
procedure out_fil;
{Процедура сохранения данных в файле}
var file_name : string;
begin
.....
{Задание имени файла для сохранения}
assign(F1, file_name);
{Открытие файла для записи и контроль ошибок при
...
выполнении этой операции}
repeat
write(‘Введите фамилию или * (признак окончания ввода
‘);
readln(s.name);
if s.name <> ‘*’ then
begin
writeln(‘Введите тариф’);
readln(s.tarif);
write(F1,s)
end
until s.name = ‘*’;
close(F1)
end;
procedure IN_fil;
{Процедура чтения данных из файла и
вывода на экран}
var file_name : string;
begin
...
{Задание имени файла для чтения}
assign(F1, file_name);
...
{Открытие файла для чтения и контроль ошибок при
выполнении этой операции}
writeln(‘------ Список ... -------‘);
{Заголовок списка}
repeat
{Цикл чтения данных из файла и вывода на
экран}
read(F1,s);
writeln(s.name, ‘ ‘,s.tarif)
until Eof(F1);
close(F1)
end;
begin
{ ---- Начало головной части программы ----}
repeat { Цикл сохранения данных. Если при каждом
обращении к процедуре Out_fil задавать разные имена файлов,
то этот
цикл позволит сохранить несколько списков; каждый
список в своем файле}
clrscr;
Out_fil;
writeln(‘Закончить ввод списков ? (Y/N)’);
readln;
until (c = ‘Y’) or (c=’y’);
repeat { Цикл чтения данных. Этот вариант позволяет
просмотреть списки из разных файлов, имена которых
задаются при каждом обращении к процедуре In_fil}
clrscr;
In_fil;
writeln(‘Закончить просмотр списков ? (Y/N)’);
until (c = ‘Y’) or (c=’y’);
end.
{Окончание программы}
readln(с);
7.7. Варианты заданий
Таблица 7.1
№
Тип
Задание
варианта
данных
имени
об
операций над
(табл.
файла
ошибках
данными (табл. 7.5)
7..2)
(табл. 7.3)
(табл. 7.4)
1
1
2
1
2
2
1
2
1
2
1
3
2
1
2
4
1
1
2
1
3
2
1
2
1
1
2
3
4
2
1
4
2
1
1
1
4
2
2
2
2
2
2
3
4
1
1
4
2
1
1
1
5
2
2
2
2
2
2
3
5
1
1
4
2
1
1
1
6
2
2
2
2
2
1
3
6
1
2
4
1
2
3
4
5
6
7
8
9
10
Сообщение Последовательность
11
12
13
14
15
16
17
18
19
20
2
1
2
1
7
2
1
2
2
2
2
3
7
1
1
4
1
2
2
4
2
1
1
3
1
1
2
2
3
2
1
1
2
1
1
1
8
2
2
2
3
2
2
3
4
1
1
4
3
1
1
1
5
2
2
2
3
2
1
3
6
2
2
4
3
1
1
1
7
2
2
2
3
2
1
3
8
1
2
4
Таблица 7.2
№ варианта
Тип данных в файле
1
Текст
2
Вещественные числа
3
Целые числа
4
Записи со структурой табл. 7.6
5
Записи со структурой табл. 7.7
6
Записи со структурой табл. 7.8
7
Записи со структурой табл. 7.9
8
Записи со структурой табл. 7.10
Таблица 7.3
№
Таблица 7.4
Вариант
варианта задания имени
№
Вариант вывода
варианта
сообщений об ошибках
1
Краткий
2
Расширенный
файла
Ввод с
1
клавиатуры
Строковая
2
константа в
программе
Таблица 7.5
№
Вариант цепочки операций над данными
варианта
1
Ввод с клавиатуры и запись в массив, запись из массива в
файл, чтение из файла и вывод на экран
2
Ввод с клавиатуры и запись в файл, чтение из файла и
вывод на экран, дополнение файла
Ввод с клавиатуры и запись в файл, чтение из файла и
3
запись в массив, вывод из массива на экран
Ввод с клавиатуры и запись в массив, запись из массива в
4
файл, дополнение файла, чтение из файла и вывод на
экран
Структуры данных для программы (к табл. 7.2)
Таблица 7.6
Таблица 7.7
Товар
Сотрудник
Наименование Цена Количество
Фамилия Должность Оклад
Таблица 7.8
Таблица 7.9
Студент
Фирма
Фамили Экзаменационные оценки
я
Названи
Курс акций
е
Математик Информатик
а
а
Таблица 7.10
Автомобиль
Марка
Мощность
Максимальная
скорость
покупк
продаж
а
а
7.8. Содержание отчета (см. п. 1.10)
7.9. Контрольные вопросы
1. Что такое «файл»?
2. Что такое «указатель текущей записи»?
3. Какую структуру может иметь имя файла?
4. Из каких элементов может состоять файл? Как нумеруются
элементы файла?
5. Каково назначение переменных файлового типа? Как могут
быть определены такие переменные в Pascal-программе?
6. Каков состав и каково назначение установочных и
завершающих
операций
с
файлами?
Какие
параметры
используются при обращении к соответствующим процедурам?
7. Каковы правила записи операторов чтения из файла и
записи в файл?
8. Как происходит выполнение процедур чтения из файла
(записи в файл)?
9. Какая процедура предназначена для явного изменения
значения
текущего
указателя
в
файле?
Какие
параметры
используются при этом?
10. Каково назначение функций FileSize, FilePos, EOF?
11. Как организовать обработку ошибок при работе с
файлами? Каков алгоритм обработки? Какие операторы могут быть
использованы для этого?
12. Что такое «текстовый файл»? Как определить в Pascalпрограмме файловые переменные для работы с текстовыми
файлами?
13. Какие процедуры используются для открытия текстовых
файлов, для чтения из файла, записи в файл?
14. Как организовать сохранение в файле данных, вводимых с
клавиатуры?
15. Как организовать чтение данных из файла и вывод на
экран?
Download