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

Delphi

.pdf
Скачиваний:
27
Добавлен:
13.04.2015
Размер:
1.18 Mб
Скачать

3 ЯЗЫК ПРОГРАММИРОВАНИЯ Object Pascal

программы. Признаком конца файла является символ #26, на экране может отображаться как ^Z, (см. рис. 3.10).

Рис. 3.10 Структура текстового файла

Текстовые файлы можно обрабатывать только последовательно. Ввод и вывод нельзя осуществлять одновременно для одного и того же файла. Работа с файлами в Object Pascal осуществляется через файловые переменные. Такие переменные для текстовых файлов объявляются следующим образом:

Var < идентификатор файловой переменной >: TextFile;

Например, Var F1,F2: TextFile означает, что мы можем работать одновременно с двумя текстовыми файлами, обращаясь к ним по именам F1 и F2, которые и являются файловыми переменными.

Существуют стандартные процедуры для работы с текстовыми файлами через файловые переменные:

AssignFile(<идентификатор файловой переменной>, '<имя файла>') – связывает файловую переменную с именем файла на диске. В качестве имен файлов можно использовать стандартные имена: Con – консоль, т.е. клавиатура и дисплей; Prn – принтер; Nul – " пустой" файл. При чтении из Nul сразу же обнаруживается конец файла, а при записи ничего не происходит.

Append(<идентификатор файловой переменной>) – открывает существующий файл для последовательной записи (добавления) данных в конец файла. Если файл был открыт, то сначала он закрывается, а затем заново открывается. Кроме того, с файлом связывается свободный буфер записи.

Rewrite(<идентификатор файловой переменной>) – создаёт и открывает файл для записи данных. Если файл с указанным именем уже существует на диске, то он удаляется и создается новый. Кроме того, с файлом связывается свободный буфер записи.

Reset(<идентификатор файловой переменной>) – открывает существующий файл только для чтения. Если файл был открыт, то сначала он закроется, а затем заново откроется.

70

3.6 ОПИСАНИЯ ТИПОВ

Read(<идентификатор файловой переменной>, <список переменных>) – читает информацию из файла в переменные, указанные в списке. Процедура чтения зависит от типа переменной стоящей в списке. Если очередная переменная – символьного типа, то в нее помещается один следующий символ из файла (включая EOLn, EOF). Если очередная переменная – арифметического типа, то далее считывается арифметические символы до появления пробелов, табуляции, EOLn или EOF. При чтении данных в строковую переменную передаются все символы до появления маркеров EOLn или EOF, маркер в строку не заносится. После последнего прочитанного символа запоминается текущая позиция в файле. Новый оператор Read будет читать не с начала файла, а с текущей позиции.

ReadLn(<идентификатор файловой переменной>, <список переменных>) – отличается от Read тем, что после чтения указанных переменных пропускаются все символы до конца строки и осуществляется переход к новой строке, начало которой становится текущей позицией.

ReadLn(<идентификатор файловой переменной>) без списка переменных вызывает продвижение текущей позиции в файле к началу следующей строки.

Write(<идентификатор файловой переменной>,<список переменных и выражений>) – записывает информацию в конец файла из указанных в списке переменных. Для символьных, арифметических, строковых и логических переменных выводятся их значения в соответствие с заданным форматом.

WriteLn(<идентификатор файловой переменной>, <список переменных и выражений>) – отличается от Write тем, что после вывода всех переменных в файл записывает маркер конца строки – EOLn.

CloseFile(<идентификатор файловой переменной>) – закрывает файл и, если он был открыт для записи, – освобождает связанный с ним буфер. Файл открытый для записи обязательно надо закрыть, т.к. при этом дозаписываются данные, хранящиеся в буфере. В противном случае эти данные могут быть потеряны, а буфер будет недоступен для записи новых файлов.

П р и м е р 3.29

Пусть файл example.txt содержит текст:

Пример:

2 + 3.5Е01 равно:

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

71

3 ЯЗЫК ПРОГРАММИРОВАНИЯ Object Pascal

var

 

 

N1,N2,res : Double;

 

{для чтения данных}

StrSgn : String[3];

 

{ для строки с операцией}

F : TextFile;

 

{файловая переменная}

begin

 

 

AssignFile(F,'example.txt');

{Связать переменную F

 

 

с файлом example.txt}

Reset(F);

{Открыть файл example.txt для чтения}

ReadLn(F);

 

{Пропустить слово "пример"}

Read(F,N1,StrSgn,N2); {Прочитать данные и строку операции}

Append(F);

{Закрыть и открыть файл для добавления}

WriteLn(F);

{Перейти на новую (третью) строку}

Case Sgn[2] of

{Взять операцию – второй символ в строке}

’+’ : res := N1+N2;

 

’-’ : res := N1-N2;

 

’*’ : res := N1*N2;

 

’/’ : res := N1/N2;

 

end;

Write(F, FormatFloat('#.###E+00', res)); CloseFile(F);

end;

После работы данного блока программы содержимое файла example.txt примет вид:

Пpимеp: 2+3.5E01 равно: 3.7E+01

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

EOF(<идентификатор файловой переменной>): Boolean – возвращает True, если следующий за последним прочитанным символом – маркер конца файла.

EOLn(<идентификатор файловой переменной>): Boolean – возвращает True, если следующий за последним прочитанным символом – маркер конца строки.

SeekEOF(<идентификатор файловой переменной>):Boolean – функция аналогичная EOF, но игнорирует пробелы, табуляцию и EOLn. Это функция бывает очень полезной при чтении числовых данных из текстового файла.

SeekEOLn(<идентификатор файловой переменной>): Boolean – функция аналогичная EOLn, но игнорирует пробелы и табуляцию.

72

3.6 ОПИСАНИЯ ТИПОВ

Теперь приведем наиболее часто используемые процедуры и функции для управления файлами и папками:

ChDir(Path: String) – эта процедура устанавливает новую текущую папку, для которой в параметре Раth заданы имя устройства, путь до папки и ее имя.

CreateDir(Dir: String): Boolean – функция создает новую папку, для которой в параметре Dir указаны имя устройства, путь до папки и ее имя. Функция возвращает значение True, если папка успешно создана, и Fа1sе – в противном случае.

DeleteFile(FileName: String): Boolean – функция удаляет файл, заданный параметром FileName, на соответствующем устройстве. Параметр FileName содержит полное имя файла. Если файл успешно удален, функция возвращает значение True, в противном случае – False.

DiskFree(Drive: Byte): Int64 – функция возвращает число свободных байт памяти на устройстве Drive. Параметр Drive имеет следующие значения: 0 – текущее устройство, 1 – устройство А:, 2 – устройство В: и т.д.

FileExists(FileName: String): Boolean – функция возвращает значение

True, если файл с именем FileName существует, и False – иначе.

FileSearch(Name, DirList: String): String – функция ищет файл с именем

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

GetCurrentDir: String – функция возвращает в виде строки устройство, путь и имя текущей папки.

MkDir(Path: String) – создает новую папку, для которой в параметре Path заданы имя устройства, путь до папки и ее имя.

RemoveDir(Dir: String): Boolean – удаляет пустую папку, заданную строкой Dir. Если папка успешно удалена, функция возвращает значение True, в противном случае – False.

RenameFile(OldName, NewName: String): Boolean – переименовывает файл с именем OldName в файл с именем NewName. Если переименование прошло успешно, функция возвращает значение Тrue, в противном случае –

False.

SetCurrentDir(Dir: String) – функция делает текущей папку, заданную строкой Dir. Если заданная папка стала текущей, функция возвращает значение Тrue, в противном случае – False.

Кроме перечисленных процедур и функций, для комфортного диалога выбора нужного файла, на странице Dialogs палитры компонент существуют два компонента:

73

3 ЯЗЫК ПРОГРАММИРОВАНИЯ Object Pascal

TOpenDialog – показывает стандартное диалоговое Windows-окно выбора файла для его открытия. Его основные свойства: FileName: string – содержит имя и путь к выбранному файлу; InitialDir: string – задает текущую папку, для которой будет открыто диалоговое окно; Title: string – задает заголовок диалогового окна; Options – множество значений, позволяющих настраивать внешний вид и поведение диалогового окна. Основной метод – это Execute: Boolean, именно он показывает диалоговое окно. Метод возвращает True, если пользователь выбрал файл и нажал кнопку Open. Если пользователь нажал Cancel, то метод возвращает False.

TSaveDialog – показывает стандартное диалоговое Windows-окно выбора файла для сохранения в нем данных. Его основные свойства

FileName, InitialDir, Title, Options и метод Execute аналогичны предыду-

щему компоненту.

Указанные компоненты применяются для получения имени файла (в свойстве FileName), которое дальше можно использовать для сохранения данных или открытия файла тем или иным способом (Append, Rewrite,

Reset).

В заключение раздела укажем два полезных метода чтения и записи в файл «оптом» списка строк для компонента TStrings. Как Вы помните из раздела 3.2.1, данный компонент является предком всех компонент, работающих со строками. Поэтому, согласно полиморфизму методов для родственных объектов, такие же методы существуют и у его потомков. Эти методы очень удобны при обработке списков строк посредством стандартных компонентов Object Pascal.

LoadFromFile(FileName: string) – читает строки из файла FileName и

заносит их в тот объект-список, к которому он применяется. Например,

RichEdit1.Lines.LoadFromFile(FileName);

SaveToFile(FileName: string) – сохраняет (перезаписывает) список строк в фал FileName из объекта-списка, к которому он применяется.

Например, ListBox1.Items.SaveToFile(FileName);

П р и м е р 3.30

Чтение из файла списка строк в ListBox1 при щелчке на кнопке Button1.

procedure TForm1.Button1Click(Sender: TObject); begin

OpenDialog1.InitialDir:=GetCurrentDir;

{ - папка диалогового окна совпадает с текущей папкой приложения}

OpenDialog1.Title:='My Open-file dialog';

If OpenDialog1.Execute Then

//если файл выбран,

Begin

//загрузить файл в ListBox1:

ListBox1.Items.LoadFromFile(OpenDialog1.FileName);

74

3.6 ОПИСАНИЯ ТИПОВ

Button1.Hint:=OpenDialog1.FileName;

{ - показывать имя файла в подсказке для кнопки Button1: }

Button1.ShowHint:=True; end;

end;

Задание 8.

Работа с файлами

Цель задания

Получение практических навыков работы с файлами.

Постановка задачи

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

Рекомендации

Для просмотра содержимого файлов целесообразно их загружать в компоненты ListBox или Memo методом LoadFromFile. Однако обработку данных файла необходимо организовать операторами обработки отдельных элементов файла через файловые переменные. Например, для чтения и обработки всех данных из файла (пока не встретится конец файла EOF) можно использовать следующую конструкцию построчного чтения:

while not SeekEOF(myFile) do begin

while not SeekEOLn(myFile) do begin

Read(myFile, ...); // - чтение всех данных строки //... обработка данных

end;

ReadLn(myFile); // - переходим на следующую строку end;

Для открытия и закрытия файлов, если это удобно, создайте в конце модуля разделы инициализации и завершения (см. раздел 2.3), например,

Initialization

AssignFile(F1,'example.txt');

Rewrite(F1);

Finalization

CloseFile(F1);

75

3 ЯЗЫК ПРОГРАММИРОВАНИЯ Object Pascal

Варианты задания

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

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

3.Проанализировать данные исходного файла и записать в новый файл соответствующей папки данные об абитуриентах, имеющих более 4.5 балла за аттестат;

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

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

6.Проанализировать данные исходного файла и записать в новый файл соответствующей папки фамилии абитуриентов, сдавших вступительные экзамены и которые старше 20 лет;

7.Проанализировать данные исходного файла и записать в новый файл соответствующей папки фамилии абитуриентов в алфавитном порядке (только по первой букве);

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

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

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

Контрольные вопросы для сдачи лабораторной работы:

1.Для чего предназначены файловые переменные?

2.Что такое текущая позиция в файле и как её можно изменить?

3.Что такое признак конца строки и конца файла?

4.Как открыть существующий файл для чтения или записи данных? В какое место текстового файла эти данные можно записывать?

5.Как создать новый файл?

6.Как при чтении файла пропустить строку?

7.Какие методы работы с файлами Вы знаете для данных типа TStrings?

76

3.7 ПРОЦЕДУРЫ И ФУНКЦИИ

3.7 ПРОЦЕДУРЫ И ФУНКЦИИ

Для многократного выполнения одинаковых алгоритмов с разными исходными данными их оформляют в виде процедур и функций. Процедуры и функции могут быть локальными, т.е. описываться и использоваться только внутри какого-либо блока, например, - внутри некоторого обработчика события. Процедуры и функции могут быть глобальными, т.е. описываться в разделе Implementation какого-либо модуля и использоваться всеми блоками текущего модуля и даже другими модулями. В последнем случае заголовок процедуры и функции должен быть продублирован в конце раздела Interface, непосредственно перед словом Implementation. Не забудьте при этом сделать текущий модуль доступным для других модулей. Подробно о взаимодействии модулей было рассказано в разделе “ Блоки локализации параметров”.

Кроме того процедуры и функции могут быть методами какого-либо класса, что ранее обсуждалось в разделе “ Классы и объекты”. Для объявления нового метода в классе, необходимо после описания блока процедуры или функции в разделе Implementation, продублировать (объявить) её заголовок внутри требуемого класса в разделе Public (см. пример 3.31 для класса TForm1).

3.7.1 Описание процедур, оператор процедуры (Procedure)

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

Procedure <имя процедуры>[(<список формальных параметров>)];

Тело процедуры, т.е. алгоритм вычислений, следует за её заголовком в виде одного составного оператора. Процедура вызывается для выполнения с помощью оператора вызова процедуры в виде её имени:

<имя процедуры>[(<список фактических параметров>)];

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

Procedure FormatHardDrive;

{процедура форматирования

 

жесткого диска}

Procedure SetUserName(X: String);

{процедура установки

 

 

имени пользователя}

Вызов данных процедур осуществляется операторами

77

3 ЯЗЫК ПРОГРАММИРОВАНИЯ Object Pascal

FormatHardDrive; SetUserName(’Vova’);

3.7.2 Описание функций, операнд функции (Function)

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

Function <имя функции>[(<список формальных параметров>)]: <тип имени>;

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

При необходимости, функцию можно использовать как процедуру, при этом должен быть установлен режим компиляции Project→Options→ Compiler→Extended syntax. В этом случае обращение к функции аналогично обращению к процедуре.

3.7.3 Перегружаемые процедуры и функции

Вы можете объявить несколько процедур (функций) в одном и том же блоке с одним и тем же именем. Такие процедуры называются перегружаемыми overload. Например,

Function Divide(X, Y: Real): Real; overload; begin

Result:=X/Y; end;

Function Divide(X, Y: Integer): Integer; overload; begin

Result:=X div Y; end;

Компилятор распознает необходимую функцию по количеству и типу фактических параметров. Например, операнд Divide(6.0, 3.0) вызовет для работы первую функцию.

78

3.7 ПРОЦЕДУРЫ И ФУНКЦИИ

П р и м е р 3.31

Опишем функцию Max как метод класса TForm1 для вычисления максимального элемента одномерного массива. Далее, при щелчке на кнопке Button1 в соответствующем обработчике события заполним одномерный массив числами из списка Memo1 (по одному числу в каждой строке), вычислим максимальный элемент массива и добавим его квадрат в новую строку списка.

unit Unit1; interface

uses Windows,Messages,SysUtils,Classes,Graphics, Controls,Forms,Dialogs;

type

 

MyArray=Array of Double;

//глобальный тип-массив

type

TForm1 = class(TForm) Button1: TButton; Memo1: TMemo;

Procedure Button1Click(Sender: TObject); private {Private declarations}

public {Public declarations}

Function Max(AMass: MyArray): Double; //новый метод end;

var Form1: TForm1;

implementation

{$R *.DFM}

{-------------- Описание функции Max как метода в классе TForm1 -----------

с формальным параметром A }

Function TForm1.Max(AMass: MyArray): Double;

Var i: Integer;

// Локальная переменная

begin

 

Result:=AMass[0];

 

For i:=1 To Length(AMass)-1 Do

 

If Result<AMass[i] Then Result:=AMass[i]; end; {Конец описания функции Max}

{----------------------

Обработчик клавиши Button1Click ------------------------

}

procedure TForm1.Button1Click(Sender: TObject);

Var

i : Integer;

79

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