Довольно часто вполне оправданным является представление некоторых элементов в качестве составных частей другой, более крупной логической единицы. представляется естественным сгруппировать информацию о номере дома, названии улицы и городе в единое целое и назвать адресом, а объединенную информацию о дне, месяце и годе рождения - датой. В языке Паскаль для представления совокупности разнородных данных служит комбинированный тип запись.Запись и массив схожи в том, что обе эти структуры составлены из ряда отдельных компонент. В то же время, если компоненты массива должны быть одного типа, записи могут содержать компоненты разных типов.Приведем пример описания переменной, имеющей структуру записи:Var
Address : Record
HouseNumber : Integer;
StreetName : String[20];
CityName : String[20];
PeopleName : String;
End;
Отметим, что поля StreetName и CityName имеют одинаковый тип: String[20]. Поскольку в описании эти поля могут располагаться в любом порядке, то можно сократить описание записи с полями одинакового типа. Сокращенное описание записи Address выглядит следующим образом:Var
Address : Record
HouseNumber : Integer;
StreetName, CityName : String[20];
PeopleName : String;
End;
Каждая компонента записи называется полем. В переменной записи Address поле с именем HouseNumber само является переменной типа Integer, поле StreetName - двадцатисимвольной строкой и т.д.
Для того чтобы обратиться к некоторому полю записи, следует написать имя переменной и имя поля. Эти два идентификатора должны разделяться точкой.Оператор, который присваивает полю HouseNumber значение 45, выглядит так:Address.HouseNumber := 45;Таким же образом присваиваются значения другим полям записи Address :Address.StreetName := 'Профсоюзная';
Address.CityName := 'Сургут';
Address.PeopleName := 'Петрова Алла Ивановна';
Каждое поле записи Address можно рассматривать как обычную переменную, которую можно напечатать или использовать в расчетах. Вместе с тем запись может использоваться как единое целое. В этом случае надо ввести тип записи.
Предположим, имеется следующее описание:Type
Date = Record
Day : 1..31;
Month : (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec);
Year : Integer;
End;
Var
HisBirth, MyBirth : Date;
После приведенного описания переменные HisBirth и MyBirth имеют тип записи Date. Помимо действий над отдельными полями записей HisBirth и MyBirth можно выполнять операции над всей записью. Следующий оператор присваивания устанавливает равенство значений записей HisBirth и MyBirth :HisBirth := MyBirth;Это присваивание эквивалентно следующей последовательности операторов:HisBirth.Day := MyBirth.Day;
HisBirth.Month := MyBirth.Month;
HisBirth.Year := MyBirth.Year;
Для переменных одного типа можно проверить выполнение отношения равенства или неравенства ("=", "<>"). После выполнения приведенных выше присваиваний следующее булево выражение будет иметь значение True:HisBirth = MyBirth;Рассмотрите пример описания процедуры, которая получает запись в качестве параметра-значения и печатает дату в сокращенной стандартной форме, используя формат (MM-DD-YYYY).Procedure WriteDate(OneDate : Date);
Begin
Write(Ord(OneDate.Month)+1);
Write('-');
Write(OneDate.Day:2);
Write('-');
Write(OneDate.Year:4);
End;
Так как на тип компонент массива не накладывается ограничений, то можно использовать массив, компонентами которого являются записи. Посмотрите описание такого массива:Var
Birthdays : Array [1..Persons] of Date;
Чтобы обратиться к некоторому полю определенной записи массива, следует определить имя массива, индекс интересующей записи и имя необходимого поля. Например, следующий оператор печатает содержимое поля Year записи Birthdays[3]:Write(Birthdays[3].Year);Примечание. Поля записи в свою очередь тоже могут быть массивами, множествами, записями.
Вопрос28. Оператор with.
В операциях над записями оператор with удобно использовать
для краткого обращения к полям записи. В операторе with к полям
одной или более конкретных переменных типа запись можно обращать-
ся, используя только идентификаторы полей. Оперaтор with имеет
следующий синтаксис:
┌────┐ ┌───────────────┐ ┌──┐ ┌────────┐
оператор ──>│with├─────>│ ссылка на ├──┬─>│do├──>│оператор├>
with └────┘ ^ │переменную типа│ │ └──┘ └────────┘
│ │ запись │ │
│ │ или объект │ │
│ └───────────────┘ │
│ ┌───┐ │
└────────┤ , │<────────┘
└───┘
ссылка на переменную ┌────────────────────┐
типа запись или объект ───>│ссылка на переменную├──>
Возьмем следующее описание:
type
TDate = record
Day : Integer:
Month : Integer;
Year : Integer:
end;
var OrderDate: TDate;
С учетом данного описания приведем пример оператора with:
with OrderDate do
if Month = 12 then
begin
Month := 1;
Year := Year + 1
end else
Month := Month + 1;
Это эквивалентно следующему:
if OrderDate.Month = 12 then
begin
OrderDate.Month := 1;
OrderDate.Year := TDate.Year + 1
end
else
Date.month := TDate.Month + 1; В операторе with сначала производится проверка каждой ссылки
на переменную, а именно: можно ли ее интерпретировать, как поле
записи. Если это так, то она всегда интерпретируется именно таким
образом, даже если имеется доступ к переменной с тем же именем.
Допустим описаны следующие переменные:
type
TPoint = record
x,y: Integer;
end;
var
x: Point;
y: Integer;
В этом случае и к x, и к y можно обращаться, как к перемен-
ной или как к полю записи. В операторе:
with x do
begin
x := 10;
y := 25;
end;
x между ключевыми словами with и dо относится к переменной типа
указатель, а в составном операторе x и y ссылаются на x.x и y.y.
Оператор:
with V1,V2,...Vn do s;
эквивалентен операторам:
with V1 do
with V2 do
...
with Vn do
S;
В обоих случаях, если Vn является полем и v1, и v2, то она
интерпретируется как v2.Vn, а не как v1.Vn.
Если выборка переменной типа запись связана с индексировани-
ем массива или разыменованием указателя, то эти действия произво-
дятся до того, как будет выполняться составной оператор.
Вопрос29. Модуль CRT
Модуль Crt позволяет выводить цветные символы на цветном экране. Хотя по-прежнему отображение будет происходить в текстовом режиме. Текстовый режим означает, что на экране могут выводиться только определенные символы в определенных местах (знакоместах). Можно представить экран, разделенным вертикальными и горизонтальными линиями на ячейки. В эти ячейки можно «вписывать» различные символы. У каждой ячейки есть адрес.Модуль Crt содержит ряд процедур, позволяющих задавать цвет символов и экрана, очищать экран, менять позицию курсора и др.Стандартный экран в Паскале чаще формируется из 25 сток и 80 столбцов. Строки нумеруются сверху вниз, а столбцы слева на право. Нумерация начинается с единицы (что может показаться непривычным).Количество доступных цветов (для экрана и символов) всего 16. Они кодируются числами от 0 до 15. Также вместо чисел можно прописывать названия цветов.
Для того чтобы в программе можно было использовать содержимое модуля Crt, его надо импортировать (подключить) в программу. Делается это в секции, которая начинается со слова uses.Чтобы очистить экран от всех надписей, требуется выполнить процедуру clrscr. Если перед этим был задан цвет экрана (с помощью textbackground), то экран будет залит соответствующим цветом.Цвет текста определяется процедурой textcolor, позиция курсора – gotoxy.
Для вывода символов на экран используются стандартные процедуры write и writeln.
Также существует процедура временной задержки delay (аргумент задается в микросекундах), если требуется выводить символы не сразу, а постепенно.
Driver - определяет тип графического драйвера. Для адаптера VGA/SVGA значение параметра задается константой VGA = 9. Обычно используется значение Driver, равное константе Detect=0, которая включает режим автоматического определения типа драйвера.
Mode - задает режим работы видеоадаптера. Например, для режима VGA с разрешением 640х480 значение Mode должно быть равно константе VGAHi = 2. Если значением Driver является Detect, то режим адаптера и значение Mode также определяется автоматически.
Path - указывает путь к каталогу, содержащему драйверы BGI (Borland Graphic Interface). Если драйверы BGI находятся в текущем каталоге, то значение Path задается пустой строкой: ‘’.
Пример использования процедуры с автоматическим определением драйвера и режима адаптера:
Driver := Detect;
InitGraph (Driver, Mode, ‘C:\TP\BGI’);
function GraphResult : Integer;
Возвращает результат последнего обращения к графическим процедурам в виде целочисленного кода. Если код результата равен константе grOK = 0, то ошибки нет, в противном случае по коду ошибки можно идентифицировать ее характер.
function GraphErrorMsg (Code: Integer): string;
Возвращает текстовое сообщение об ошибке графики по ее коду.
Пример использования функции:
Writeln (GraphErrorMsg (GraphResult));
procedure CloseGraph;
Завершает работу адаптера в графическом режиме, очищает экран и переводит его в текстовый режим.
2. Координаты и окна
function GetMaxX: Word;
function GetMaxY: Word;
Возвращают максимальные координаты (размеры) экрана в данном режиме в пикселях. Левый верхний угол экрана имеет координаты (0, 0).
procedure MoveTo (X, Y : Integer);
Перемещает невидимый указатель текущей позиции в точку с координатами X, Y относительно окна или экрана.
Устанавливает прямоугольное окно для вывода графической информации. Величины (X1, Y1) задают левый верхний, а (X2, Y2) – правый нижний угол окна относительно экрана. После этого координаты текущего указателя становятся относительными, т.е. отсчитываются от левого верхнего угла окна с координатами (0, 0). Параметр Clip определяет отсечку части изображения, не помещающуюся в окне. Для этого удобно использовать константы ClipOn = True и ClipOff = False.
procedure ClearViewPort;
Очищает графическое окно, закрашивает его цветом фона и устанавливает текущий указатель в левый верхний угол окна.
3. Цвета и линии
procedure SetColor (Color: Word);
Устанавливает цвет выводимых линий и символов по его коду Color в соответствии с таблицей 17.1.
procedure SetBkColor (Color: Word);
Устанавливает цвет фона.
function GetColor: Word;
function GetBkColor: Word;
Возвращает код текущего цвета линий и фона.
procedure PutPixel (X, Y: Integer; Color: Word);
Выводит заданным цветом точку с координатами X, Y.
procedure Cyrcle (X, Y: Integer; R: Word);
Вычерчивает текущим цветом окружность с радиусом R и координатами центра X, Y.
procedure Line (X1, Y1, X2, Y2: Integer);
Выводит текущим цветом прямую линию с координатами X1, Y1 начала и X2, Y2 конца.
procedure Rectangle (X1, Y1, X2, Y2: Integer);
Вычерчивает текущим цветом прямоугольник с координатами X1, Y1 левого верхнего и X2, Y2 – правого нижнего угла.
Выводит строку с позиции, заданной координатами X, Y.
С помощью этих процедур можно выводить также русский текст, если на компьютере установлен соответствующий драйвер.
Имеется также ряд процедур и функций, управляющий шрифтами и расположением текста.
Замечание по разделу. Материал данного раздела носит обзорный характер. Примеры программ с использованием модулей CRT и Graph приводятся в разделах «Динамические списки» и «Объектно-ориентированное программирование».
Вопрос31. Инициализация графики, подготовительные работы, управление цветом, закрытие режима
Графический режим
Стандартное состояние компьютера после запуска Турбо Паскаля – текстовый режим. Для того, чтобы использовать его графические средства, программист должен "определенным образом инициировать режим работы дисплейного адаптера". В графическом режиме работой дисплейного адаптера управляет графический драйвер.
Драйвер – это специальная программа, которая управляет техническими средствами компьютера. Для всех существующих типов адаптеров фирма Borland разработала графические драйверы (они имеют расширение .bgi и находятся на диске в одноименном подкаталоге).
Необходимые процедуры и функции для работы с графикой собраны стандартном модуле – Graph. Инициализация графики производится с помощью процедуры InitGraph, которая имеет вид:
InitGraph(GraphDriver, GraphMode, Path);
где переменные GraphDriver и GraphMode имеют тип Integer, а переменная Path имеет тип String.
GraphDriver – целая переменная, определяющая тип драйвера. Процедура загружает драйвер в оперативную память и переводит адаптер в графический режим работы. Тип драйвера должен соответствовать типу графического адаптера. Для указания типа драйвера в модуле предопределены следующие константы:
Таблица 1. Типы драйверов.
CGA
EGA
EGAMono
HercMono
VGA
MCGA
EGA64
IBM8514
ATT400
PC3270
Целая переменная GraphMode задает режим работы графического адаптера. Многие адаптеры могут работать в нескольких режимах. Например, переменная GraphMode в момент обращения к InitGraph может иметь одно из следующих значений для адаптера VGA:
VGALo = 0; VGAMed = 1; VGAHi = 2;
Теперь представьте такой вариант: Вам нужно написать программу на языке Pascal с использованием графических возможностей компьютера. Хорошо, если это – программа для компьютера с известным адаптером. А если нет, как действовать в этом случае? Выход один. Если нам неизвестен тип адаптера или программа должна работать с любым адаптером, необходимо обращаться к InitGraph с запросом на автоматическое определение драйвера.
Это происходит следующим образом: переменной GraphDriver присваиваем значение detect. В этом случае компьютер сам определит необходимый драйвер и подберет наилучший режим.
Program Primer1;
Uses
Graph;{Подключение модуля библиотеки графических процедур}
Var
GraphDriver,
GraphMode : integer;
Begin
GraphDriver := detect; {автоопределение типа драйвера }
InitGraph(GraphDriver, GraphMode, Path);
{Инициализация графического режима}
. . .
. . .
. . .СloseGraph;{Закрытие графического режима}
End.
Условно весь модуль Graph можно подразделить на несколько функциональных групп по выполняемым действиям. Рассмотрим эти группы (внутри групп взяты основные функции, необходимые нам для первоначального ознакомления с графикой):
1) Инициализация графики, подготовительные работы, управление цветом, закрытие режима:
InitGraph
установление (инициализация) графического режима работы
CloseGraph
завершение работы с графикой
DetectGraph
определение драйвера
FloodFill
заливка замкнутого контура выбранным типом и цветом палитры
RestoreCRTMode
возврат в текстовый режим
SetBkColor
выбор и установка нового цвета закраски фона
SetColor
выбор и установка нового текущего цвета
SetFillStyle
выбор и установка нового шаблона и цвета заполнения
2) Процедуры и функции для управления курсором и видеостраницами:
ClearDevice
очистка текущего устройства вывода
ClearViewPort
очистка текущего окна
GetMaxX
получение максимально доступной координаты по оси X
GetMaxY получение максимально доступной координаты по оси Y
GetPixel
получение текущего цвета точки экрана
GetX
получить значение координаты X
GetY
получить значение координаты Y
MoveRel
переместить курсор из данной текущей точки на заданное приращение.
MoveTo
переместить курсор из данной текущей точки в заданную точку
3). Процедуры и функции для работы с "графическими примитивами":
Arc
Рисует дугу
Bar
Рисует полосу
Bar3D
Рисует трехмерную полосу
Circle
Рисует окружность
DrawPoly
Рисует многоугольник
Ellipse
Рисует эллиптическую дугу или эллипс
FillEllipse
Рисует заполненный эллипс
FillPoly
Заполняет многоугольник
Line, LineRel, LineTo
Рисует линию
Rectangle
Рисует прямоугольник
Sector
Рисует сектор эллипса
PutPixel
Рисует точку
4) Процедуры для работы с текстом
OutText
Вывод текста
OutTextXY
Вывод текста
Чтобы точно строить изображение на экране, Вам нужно сначала нарисовать, как это должно выглядеть на бумаге. Для этого начертите в тетради систему координат графического режима.
Итак, отсчет начинается с верхнего левого угла с координатами (0;0), значение Х – столбец, отсчет слева направо; значение Y – строка, отсчет сверху вниз.
Для задания цвета точки можно использовать как слово на английском языке, так и цифру из следующей таблицы:
Circle (X, Y, R), где переменные X, Y, R типа Word – Рисуется окружность в центре (X, Y) c радиусом R.
Arc (X, Y, BegA, EndA, R), где переменные X, Y, BegA, EndA, R типа Word – Рисуется дуга (часть окружности) с координатами центра (X, Y), с радиусом R, которая начинается от угла BegA до угла EndA в полярной системе координат.
Например, чтобы начертить дугу (смотри рисунок) от окружности радиуса 50 пикселей и координатами центра (100, 230) надо набрать команду: Arc (100, 230, 45, 135, 50)
Нетрудно заметить, что если мы будем чертить дугу от 0 до 360, то начертим окружность.
Ellipse(X, Y, BegA, EndA , хR, yR), где переменные X, Y переменные типа integer, а BegA, EndA, хR, yR типа Word – рисуется дуга эллипса, у которого центр находится в точке (X, Y), BegA – начальный угол, EndA – конечный угол, хR – радиус по горизонтальной оси, yR – радиус по вертикальной оси.
Например, чтобы начертить дугу ABC от эллипса надо дать такую команду Ellipse(150, 200, 30, 240, 80, 50).
Вполне очевидно, чтобы начертить весь эллипс надо определить углы черчения дуги от 0 до 360. А также, чтобы “вытянуть” эллипс вверх надо радиус по вертикальной оси сделать больше, чем по горизонтальной (если радиусы будут равны, то будет начерчена дуга окружности или сама окружность).
Rectangle (X1, Y1, X2, Y2), где переменные X, Y переменные типа integer – рисуется прямоугольник, X1, Y1 – координаты верхнего левого угла, X2, Y2 – координаты нижнего угла.
SetLineStyle (Type, Pattern, Thick), где переменные X, Y переменные типа Word – устанавливает стиль линий. Здесь Type – тип линии, Pattern – образец линии, Thick – толщина линии. Тип линии может быть задан с помощью одной из следующих констант:
0 – непрерывная линия
1 – линия из точек
2 – линия из точек и тире
3. – пунктирная линия
4 – линия,задаваемая пользователем
Параметр Pattern учитывается только для линий, вид которых определяет пользователь. Пользователь таким образом может задать линии в виде отрезков длиной до 16 пиксель.
Толщина линий.
1 – толщина в один пиксель
3 – толщина в три пикселя
Установка стиля и цвета закраски. Закрашивание фигур
SetFillStyle (Pattern, Color), где переменные Pattern, Color типа Word – определяет стиль заполнения и цвет заполнения.
Значения Pattern можно взять из следующей таблицы:
Стандартные стили заполнения
Константа
Код
Маска-заполнение
EmptyFill
цветом фона
SolidFill
текущим цветом
LineFill
символами - -, цвет – Color
LtSlashFill
символами //норм. толщины, цвет – Color
SlashFill
символами //удвоенной толщины, цвет – Color
BkSlashFill
символами \\удвоенной толщины, цвет – Color
LtBkSlashFill
символами \\норм. толщины, цвет – Color
HatchFill
вертикально-горизонтальная штриховка тонкими линиями, цвет – Color
XhatchFill
штриховка крест-накрест по диагонали “редкими” тонкими линиями, цвет – Color
InterLeaveFill
штриховка крест-накрест по диагонали “частыми” тонкими линиями, цвет – Color
WideDotFill
“редкие” точки
CloseDotFill
“частые” точки
Например, если мы употребили процедуру
SetFillStyle (WideDotFill, Red) или SetFillStyle (10, 4),
то выбрали стиль закраски “редкими” точками красного цвета
Теперь же, когда Вы указали компьютеру ЧЕМ Вы будете закрашивать (стиль и цвет), можно указать, ЧТО Вы будете закрашивать. Для этого существует процедура
FloodFill(X, Y, ColorBorder), где X, Y переменные типа integer, а Border – переменная типа word -процедура, которая позволяет заполнить замкнутую область выбранным стилем и цветом закраски. Необходимо только выполнить несколько требований:
· первые два параметра (X, Y) являются координатами так называемой “затравочной” точки, т. е. точки, лежащей обязательно внутри закрашиваемой области;
· ColorBorder – параметр, обозначающий цвет, которым нарисована закрашиваемая фигура (так называемый цвет “бордюрчика”);
· фигура должна быть начерчена одним цветом;
· фигура должна быть замкнута.
Например, пусть следующая фигура начерчена синим цветом
Чтобы закрасить ее выбранным стилем и цветом (“редкие” точки красного цвета, см. выше) нужно дать команду FloodFill(180, 200, 1).
Нужно представить, как компьютер закрашивает фигуру. Первое, что он делает – это находит точку, от которой он начинает заливку и заливает точку за точкой до тех пор, пока не встретит заданный цвет. Таким образом, если фигура замкнутая, то, разливаясь во все стороны, он натыкается на “бордюрчик” и фигура становится закрашенной. Но, если в контуре фигуры есть хотя бы один пиксель, закрашенный другим цветом, замкнутость фигуры нарушается и краска выливается через эту дырочку и заливает не ту область, а иногда и весь экран.
Чтобы Вас уберечь от многих ошибок и, соответственно, сохранить Ваше время, хочу посоветовать относиться к рисованию фигур и их закраске, как к аппликации. Т. е. если нарисовали фигуру, постарайтесь сразу же ее закрасить, а также рисовать фигуры, начиная от самых больших и заканчивая самыми маленькими.
SetBkColor(Color), где переменная Color типа Word – процедура, устанавливающая цвет фона.
Примечание. После замены цвета фона на любой, отличный от черного, Вы не сможете более использовать цвет 0 как черный, он будет заменяться на цвет фона, т.к. процедуры модуля Graph интерпретируют цвет с номером 0 как цвет фона.
ClеarDeviсe – процедура, которая очищает экран и устанавливает курсор в позицию (0,0).
GraphDefaults – cбрасывает заданные пользователем параметры графического режима и устанавливает исходные (определяемые по умолчанию при запуске процедуры InitGraph).
Вывод текста
Описываемые ниже стандартные процедуры подддерживают вывод текстовых сообщений в графическом режиме. Это не одно и то же, что использование процедур Write и Writeln. Дело в том6 что специально для графического режима разработаны процедуры, обеспечивающие вывод сообщений различными шрифтами в горизонтальном или вертикальном направлении, с изменением размеров и т.д.
OutText('текст'), где переменная 'текст' типа String – выводит текстовую строку, начиная с текущего положения указателя. При горизонтальном направлении вывода указатель смещается в конец выведенного текста, при вертикальном – не меняет своего положения. Строка выводится в соответствии с установленным стилем и выравниванием.
Примечание. Если текст выходит за границы экрана, то при использовании штриховых шрифтов он отсекается, а в случае стандартного шрифта не выводится.
OutTextXY(X, Y, 'текст'), где переменные X, Y типа Integer , а 'текст' типа String – выводит строку 'текст', начиная с точки с координатами X, Y. Указатель не меняет своего положения.
Например, после применения процедуры OutTextXY(100, 50, 'Grafika in Turbo Pascal') на экране будет высвечена строка Grafika in Turbo Pascal, начиная с точки с координатами (100,50).
SetTextStyle(Font; Direct; Size), где переменные Font и Direct типа word, а Size типа Integer – устанавливает стиль текстового вывода на графический экран. Здесь переменная Font указывает на код (номер) шрифта, Direct – код направления, а Size – код размера шрифта.
Для указания кода шрифта можно использовать следующие константы:
Номер
Описание
точечный шрифт 8х8
утроенный шрифт
уменьшенный шрифт
прямой шрифт
готический шрифт
“рукописный” шрифт
одноштриховый шрифт типа Courier
красивый наклонный шрифт типа Times Italic
шрифт типа Times Roman
шрифт типа Courier увеличенного размера
крупный двухштриховый шрифт
Cреди этих шрифтов только DefaultFont (код 0) является матричным шрифтом, т.е. его символы создаются из матриц 8х8 пикселей. Все остальные шрифты – векторные, их элементы формируются как совокупность векторов определенного направления и размера.
Примечание. Русскоязычные сообщения можно выводить в графическом режиме с помощью шрифта DefaultFont.
Для задания направления выдачи текста используют следующие константы:
0 – слева направо
1 – снизу вверх
Размер выводимых символов задается параметром Size, который имеет диапазон от 1 до 10 (матричный шрифт от 1 до 32).
SetTextJustify (Horiz,Vert), где переменные Horiz и Vert типа word – задает выравнивание текста по отношению к текущему положению указателя или к заданным координатам. Здесь Horiz – горизонтальное выравнивание, а Vert – вертикальное выравнивание.
Выравнивание определяет как будет размещаться текст – левее или правее указанного места, выше, ниже или по центру.
Можно использовать следующие константы:
Для Horiz:
LeftText = 0 (указатель слева от текста);
CenterText = 1 (симметрично слева и справа);
RightText = 2 (указатель справа от текста);
Для Vert:
BottonText = 0 (указатель снизу от текста);
CenterText = 1 (симметрично снизу и сверху);
TopText = 2 (указатель сверху от текста);
Обратите внимание на неудачные имена констант. Если Вам надо расположить текст справа от заданных координат (процедура OutTextXY), то нужно задать константу LeftText, что в переводе с английского означает “Левый текст”.
SetUserCharSize (X1, X2, Y1, Y2), где переменные X1, X2, Y1, Y2 типа word – изменяет размер выводимых символов в соответствии с заданными пропорциями. Пропорции задают масштабный коэффициент, показывающий во сколько раз увеличится ширина и высота выводимых символов по отношению к стандартно заданным значениям. Коэффициент по горизонтали находится как отношение X1 к X2, по вертикали Y1, Y2. Например, чтобы удвоить ширину символов, необходимо задать Х1=2 и Х2=1. Стандартный размер символов устанавливается процедурой SetTextStyle, которая отменяет предшествующее ей обращение к SetUserCharSize.
GraphDefaults – cбрасывает заданные пользователем параметры графического режима и устанавливает исходные (определяемые по умолчанию при запуске процедуры InitGraph).
Процедуры рисования закрашенных фигур
Bar (x1,y1,x2,y2), где переменные X1, X2, Y1, Y2 типа Integer – рисуется закрашенный установленным ранее стилем и цветом прямоугольник. Координаты точек указываются аналогично процедуре рисования не закрашенного прямоугольника.
Bar3D (x1,y1,x2,y2, Depth, Top), где переменные X1, X2, Y1, Y2 типа Integer, Depth типа Word, а Top типа Boolean – рисуется параллелепипед, закрашенный текущим стилем и цветом. Здесь переменные X1, X2, Y1, Y2 являются координатами левого верхнего и правого нижнего углов передней грани, Depth – ширина боковой грани (отсчитываются по горизонтали), Top – признак включения верхней грани: TopОn = true – верхняя грань изображается, TopОff = false – верхняя грань не изображается.
PieSlice (X, Y, BegA, EndA, R), где переменные X, Y типа Integer, а BegA, EndA, R типа Word – строит сектор круга, закрашенный текущим стилем и цветом заполнения с учетом масштабов по осям. Здесь X, Y – координаты центра сектора круга, BegA – начальный угол сектора, отсчитываемый против часовой стрелки от горизонтальной оси, направленной вправо, EndA – конечный угол сектора, отсчитываемый против часовой стрелки от горизонтальной оси, направленной вправо, R – радиус сектора.
FillEllipse (X, Y, Rx, Ry), где X, Y, Rx, Ry являются переменными типа Integer обводит линией и заполняет эллипс. Здесь X, Y - координаты центра эллипса, Rx, Ry – горизонтальный и вертикальный радиусы эллипса. Эллипс обводится линией, заданной процедурами SetLineStyle и SetColor, и заполняется с использованием параметров, установленных процедурой SetFillStyle.
Sector (X, Y, BegA, EndA, Rx, Ry), где переменные X, Y типа Integer, а BegA, EndA, Rx, Ry типа Word – вычерчивает и заполняет эллипсный сектор. Здесь X, Y - координаты центра эллипса, BegA, EndA - начальный и конечный углы эллипсного сектора, Rx, Ry - горизонтальный и вертикальный радиусы эллипса.
Вопрос32. Процедуры и функции для работы с "графическими примитивами".
procedure SetPixel(x,y,color: integer);
Закрашивает один пиксел с координатами (x,y) цветом color.
function GetPixel(x,y): integer;
Возвращает текущее значение цвета для пиксела с координатами (x,y).
procedure MoveTo(x,y: integer);
Передвигает невидимое перо к точке с координатами (x,y); эта функция работает в паре с функцией LineTo(x,y).
procedure LineTo(x,y: integer);
Рисует отрезок от текущего положения пера до точки (x,y); координаты пера при этом также становятся равными (x,y).
procedure Line(x1,y1,x2,y2: integer);
Рисует отрезок с началом в точке (x1,y1) и концом в точке (x2,y2).
procedure Circle(x,y,r: integer);
Рисует окружность с центром в точке (x,y) и радиусом r.
procedure Ellipse(x1,y1,x2,y2: integer);
Рисует эллипс, заданный своим описанным прямоугольником с координатами противоположных вершин (x1,y1) и (x2,y2).
procedure Rectangle(x1,y1,x2,y2: integer);
Рисует прямоугольник, заданный координатами противоположных вершин (x1,y1) и (x2,y2).
procedure RoundRect(x1,y1,x2,y2,w,h: integer);
Рисует прямоугольник со скругленными краями; (x1,y1) и (x2,y2) задают пару противоположных вершин, а w и h – ширину и высоту эллипса, используемого для скругления краев.
procedure Arc(x,y,r,a1,a2: integer);
Рисует дугу окружности с центром в точке (x,y) и радиусом r, заключенной между двумя лучами, образующими углы a1 и a2 с осью OX (a1 и a2 – вещественные, задаются в градусах и отсчитываются против часовой стрелки).
procedure Pie(x,y,r,a1,a2: integer);
Рисует сектор окружности, ограниченный дугой (параметры процедуры имеют тот же смысл, что и в процедуре Arc).
procedure Chord(x,y,r,a1,a2: integer);
Рисует фигуру, ограниченную дугой окружности и отрезком, соединяющим ее концы (параметры процедуры имеют тот же смысл, что и в процедуре Arc).
procedure TextOut(x,y: integer; s: string);
Выводит строку s в позицию (x,y) (точка (x,y) задает верхний левый угол прямоугольника, который будет содержать текст из строки s).
procedure FloodFill(x,y,color: integer);
Заливает область одного цвета цветом color, начиная с точки (x,y).
Строит ломаную по n точкам, координаты которых заданы в массиве a элементов типа Point.
procedure Polyline(var a; n: integer);
Строит замкнутую ломаную по n точкам, координаты которых заданы в массиве a элементов типа Point.
Вопрос33. Процедуры для работы с текстом.
Для вывода на экран текста в графическом режиме используются следующие процедуры:
OutText(S); - вывод строки S (типа string) в текущей позиции курсора.
OutTextXY(x,y,S); - вывод строки S в позиции с координатами (x, y).
Строку S можно определять явно в виде символов, заключенных в апострофы, например, OutText('Sample 1');, или как переменную (константу) типа string. Если требуется вывести значение переменной числового типа, то необходимо приме-нить процедуру ее преобразования в строковый тип. Например: Str(x:10:5,S); - определяем переменную "S" (типа string), полученную преобразованием переменной "x" (вещественного типа) по указанному формату.
Перечислять несколько переменных через запятые (подобно параметрам функций write и writeln) в графических функциях вывода текста не допускается. При выводе нескольких строковых переменных они соединяются знаком "+" , например: OutText('x='+ S);
Для установки стиля вывода текста используется процедура
SetTextStyle(F, D, Z);
где F - номер шрифта, D - направление вывода надписи, Z - увеличение размера относительно базового варианта. Параметры F, D, Z - типа Word.
Шрифт в графическом режиме может создаваться двумя методами. В первом типе шрифта - матричном, берется стандартный шрифтовой набор BIOS ПК, где каждому символу соответствует матрица 8*8 пикселов. Матричный шрифт используется по умолчанию. Изменение размера матричного шрифта производится увеличением исходной матрицы в N-раз: 8N*8N пикселов. При увеличении размера явно проявляется "грубость" матричного шрифта.
Второй тип шрифтов - векторный (штриховой). При этом буквы рисуются как совокупность отрезков, соединяющих узловые точки букв. Качество в этом случае от размера не зависит. Однако вывод текста векторными шрифтами более медленный, чем матричным.
В стандартном наборе BGI определено:
F = 0 (DefaultFont) - 8х8 пикселов - матричный шрифт,
векторные шрифты:
F = 1 (TriplexFont) - триплекс (полужирный),
F = 2 (SmallFont) - уменьшенный,
F = 3 (SansSerifFont) - прямой (книжный),
F = 4 (GothicFont) - готический.
Направление шрифта: D= 0 - по горизонтали слева направо,
D= 1 - по вертикали снизу вверх, символы повернуты на 900.
Увеличение размера Z варьируется от 1 до 31 для матричного шрифта и от 1 до 10 для векторных шрифтов. Причем базовый размер соответствует для матричного шрифта Z= 1, для векторного шрифта Z= 4. При Z= 0 базовый размер устанавливается по умолчанию.
Для векторного шрифта, можно изменить его пропорции относительно базового размера процедурой
SetUserCharSize(XN, X, YN, Y);
При этом (XN/X) - множитель для изменения ширины символов, (YN/Y) - множитель для изменения высоты символов. Параметры XN, X, YN, Y - типа Word.
Текст можно выравнивать относительно позиции его вывода с помощью процедуры
(0,2) (1,2) (2,2)
SetTextJustify(H, V); * * *
(0,1)*_ЦЕНТРИРУЕМЫЙ ТЕКСТ*(2,1)
* * *
Выравнивание по горизонтали: (0,0) (1,0) (2,0)
H = 0 - текст справа от позиции вывода, В скобках указаны значения H, V.
H = 1 - центрирование текста,
H = 2 - текст слева от позиции вывода.
Выравнивание по вертикали:
V = 0 - текст выше позиции вывода,
V = 1 - центрирование текста,
V = 2 - текст ниже позиции вывода.
По умолчанию установлено H= 0, V= 2.
Длину строки S (в пикселах) можно определить функцией TextWidth(S);
Высота строки S определяется функцией TextHeight(S);
Если строка не помещается в области экрана, то в случае матричного шрифта эта строка не выводится, а для векторных шрифтов часть строки отсекается.
Цвет текста в графике устанавливается процедурой SetColor(N); где N-номер цвета.
{ -------- Пример программы, демонстрирующей различные шрифты: --------- }
uses Graph;
var Gd, Gm, k, X, Y, Size: integer; S: string;
begin
Gd:= Detect; InitGraph(Gd, Gm, 'c:\tp7\bgi');
X:= 0; Y:= 0; { начальные координаты вывода текста }
for Size:= 1 to 10 do begin k:= 0; { перебор размеров шрифта }
Y:= Y + TextHeight('S') + 1 { смещение по "Y" на высоту буквы "S" }
end;
Readln; ClearDevice;
SetTextJustify(1,2); { выравнивание по центру }
for k:= 1 to 4 do begin { пишем векторными шрифтами }
Y:= 0; SetColor(k+8);
for Size:=1 to 10 do begin { перебор размеров шрифта }
SetTextStyle(k, 0, Size); Str(Size, S);
OutTextXY( GetmaxX div 2, Y, 'Size='+S);
Y:= Y + TextHeight('S') + 1;
end;
Readln; ClearDevice
end; CloseGraph
end.
Вопрос34. Типизированные файлы. Процедуры и функции для работы с типизированными файлами
Типизированный файл - последовательность элементов одного типа.
Описание файлового типа имеет синтаксис:file of < тип элементов>
Допустим, мы имеем дело с файлом, в котором записываются переменные типа Word, тогда переменная файлового типа может быть введена двояко: с явным объявлением файлового типа:Type
WordFile = file of word;
Var
MyFile : WordFile;
или без объявления файлового типа:Var
MyFile : file of word;
Приведем примеры переменных файлового типа с другими объявлениями.Type
Student = record
Name, SerName : string;
YearOld : byte;
Sessia : array [1..10] of byte;
end;
Var
VarFile1 : file of char;
VarFile2 : file of Student;
VarFile3 : file of string;
Файловые переменные имеют специфическое применение. Над ними нельзя выполнять никаких операций (присваивать значение, сравнивать и др.). Их можно использовать только для выполнения операций с файлами (чтения, записи, удаления файла и т.д.). кроме того, через файловую переменную можно получить информацию о конкретном файле (тип, параметры, имя файла и т.д.).
По сути любой физический файл, Вы можете представить как последовательность блоков памяти описанного типа. Все компоненты файла имеют общее имя, а каждый еще и имеет свой номер. Начальный элемент имеет нулевой номер.
С каждым файлом можно связать понятие текущий указатель. Это неявно описанная переменная, которая указывает на конкретный элемент файла. Действия с файлами производятся поэлементно, причем в них участвует тот элемент, на который "смотрит" текущий указатель, перемещающийся в результате выполнения действия на следующий элемент.
А самое основное, что Вы должны уметь делать над файлом это - записать информацию из программы в файл и считать нужную информацию в выделенную переменную для обработки программой.
Процедуры и функции для работы с типизированными файлами.
Вспомним, что типизированный файл - это последовательность элементов одного типа. А раз так, то при последовательном обращении к файлу текущий указатель переходит от элемента к элементу. Возникает вопрос: можно ли игнорировать последовательный доступ к файлу и сразу, например, обратиться к третьему элементу файла? Оказывается, можно.
Если есть необходимость нарушения последовательной записи или чтения из файла, текущий указатель, может быть изменен процедуройSeek (МуFilе, n);
где n - требуемое положение указателя.
Внимание! Нумерация элементов типизированного файла начинается с нуля.
Поэтому, чтобы обратиться к третьму элементу, нужно записать Seek (МуFilе, 2).
Seek (МуFilе, 0) - устанавливает указатель в начальной позиции (на первый элемент).
Seek (МуFilе, FileSize(МуFilе)) - устанавливает указатель после последнего элемента, то есть на признак конца файла.
Примечание. Функция FileSize(МуFilе) возвращает количество элементов типизированного файла МуFilе.
Текущую позицию указателя дает функция FilePos (МуFilе);
Рассмотрите пример.
Задача. Составить программу, которая переписывает существующий файл, заменяя все латинские буквы на заглавные.Рrogram Writing;
Var
FileName : string; {строка, содержащая имя файла}
FVar : file of char; {переменная файлового типа}
Index : integer;
Letter : char; {читаемый из файла символ}
Begin
write('Enter filename: '); {предложение ввести имя файла}
readln (FileName); {ввод имени файла}
assign (FVar,FileName); {связь имени файла и переменной}
{$I-} {отключен контроль ввода/вывода}
reset (FVar); {открытие файла для чтения и записи}
{$I+} {включен контроль ввода/вывода}
if IOResult <> 0 {выход, если файл не открыт}
then
begin
writeln ('Не открыт файл ', FileName);
Halt
end;
while not EOF (FVar) do {цикл до конца файла}
begin
read (FVar, Letter); {чтение символа из файла}
Letter:=Upcase(Letter); (преобразование букв)
Seek(FVar,FilePos(FVar)-1); {перемещение указателя назад на 1 позицию}
Как Вы уже заметили в предыдущей программе была использована функция IOResult. Рассмотрим, какую роль выполняет эта функция.
Функция IOResult предназначена для поиска ошибок, возникающих при работе с файлами. Эта функция возвращает результат последней операции ввода/вывода, если автоматический контроль за ошибками, возникающими при выполнении операций ввода/вывода, отключен с помощью директивы компилятора {$I-}. При безошибочном выполнении операций ввода/вывода функция IOResult всегда возвращает результат равный нулю. Поэтому, как правило, ее используют в операции сравнения с нулем. При использовании функции IOResult нужно помнить о том, что она возвращает величину, которую можно интерпретировать как флаг ошибки лишь в том случае, когда эта функция вызывается следом за операцией ввода/вывода. А если Вы хотите провести анализ ошибки позже, Вам придется сохранить возвращаемое значение в некоторой промежуточной переменной.
Просмотрите еще раз фрагмент программы, в которой посредством процедуры reset производится попытка открытия файла. Если эта попытка не увенчалась успехом, то на экран будет выведено сообщение об ошибке.{$I-} {отключение контроля ввода/вывода}
reset (F,'C:\TP7\BIN\Text.txt'); {открытие файла для чтения}
if IOResult <> 0
then
writeln ('Ошибка при открытии файла');
{$I+} {включение контроля ввода/вывода}
В своих программах Вы должны применять функцию IOResult.
Вопрос35. Процедуры и функции для работы с файлами любого типа
Переменные файлового типа используются в программе только в качестве параметра собственных и стандартных процедур и функций. Все фактические действия с файлами основаны на наборе стандартных процедур языка, входящих в состав модулей System и Dos.
Сначала рассмотрим процедуры модуля System.
Напомним, что он подключен к программам по умолчанию, то есть его не требуется подключать к программе в разделе Uses.
До начала работы с файлами устанавливается связь файловой переменной МуFilе с именем дискового файла. Очень важно различать собственно файл (область памяти на магнитном носителе с некоторой информацией) и переменную файлового типа в некоторой Turbo Pascal-программе. Считается, что файловая переменная является представителем некоторого дискового файла в программе. Для того, чтобы реализовать доступ к файлу на магнитном диске, программа должна связать его с файловой переменной. Для этого необходимо сопоставить переменную с именем файла. Это имя представляется в виде строки, содержащей полное имя файла и, может быть, маршрута к файлу, который формируется по общим правилам MS-DOS.
здесь приведено полное (с указанием пути) имя пользовательского файла Result.dat.
Если путь не указан, программа будет искать файл только в своем рабочем каталоге и, как это принято в системе DOS, по указанным в файле аutoехес.bat путям. Кроме указания имени файла на дисковом накопителе может быть указано стандартное имя одного из устройств ввода-вывода: «соn» - консоль, то есть дисплей и клавиатура, «рrn» - или «lpt1» - принтер.
Не разрешается связывать с одним физическим файлом различные файловые переменные в программе.
До тех пор, пока файловая переменная не связана с каким-либо дисковым файлом, никакие операции с ней в программе невозможны. Заметим, что можно связать файловую переменную с еще не существующим дисковым файлом. Это делается в случае последующего создания Turbo Pascal-программой файла с данным именем с помощью специальной системной процедуры.
После того, как файловая переменная с помощью процедуры Аssign связана с конкретным дисковым файлом, можно выполнить любую допустимую операцию с ним.
Все файлы, открытые в результате работы программы, должны быть закрыты при завершении программы процедуройclosе (МуFilе);
При выполнении этого оператора закрывается физический файл на диске и фиксируются изменения, связанные с использованием данного файла. Обратите внимание на необходимость закрытия файлов во всех ветвях программы, в том числе в различных аварийных ситуациях. Незакрытые файлы нарушают файловую структуру на диске, что может приводить к серьезным проблемам с настройкой компьютера.
Открытие нового файла для записи производится процедурой, единственный аргумент которой - переменная файлового типа, например:rewrite (МуFilе);
Эта процедура создает на диске новый файл, имя которого связано с переменной МуFilе процедурой Аssign. Указатель работы с файлом помещается в начальную позицию.
Внимание! Если файл с таким именем уже существует, он становится пустым, то есть его предыдущее содержание теряется.
После выполнения процедуры rewrite файл доступен как для записи, так и для чтения.
Подготовку существующего файла для чтения и записи выполняет процедураreset (МуFilе);
Эта процедура ищет уже существующий файл на диске и открывает его для работы, помещая указатель в начальную позицию. Если файл с установленным в Аssign именем не найден, возникает ошибка ввода/вывода, контроль которой зависит от директивы компилятора {$I} (смотрите ниже).
Внимание! Файл в данный момент времени может быть в одном из двух состояний: либо только для записи, либо только для чтения.
Запись в файл производится процедуройwrite (МуFilе, var1, var2, ...., varN);
Первый аргумент этой процедуры - переменная файлового типа, далее следует список записываемых переменных, которые должны соответствовать обьявленному типу файла. При выполнении этой операции текущий указатель файла смещается на число позиций, равное числу переменных.
Чтение из файла производится аналогичной процедурой:read (МуFilе, var1, var2, ...., varN);
Положение элементов в файле нумеруется, начиная с номера 0 для первого элемента. После последнего элемента файла автоматически записывается признак конца файла.
Функция FileSize(МуFilе) определяет число элементов в файле.
Функция логического типа ЕОF(МуFilе) имеет значение Тrие, если указатель указывает на маркер конца файла (End Of file).
Длина файла, то есть количество элементов в этой последовательности - величина произвольная, изменяемая в процессе работы. Работа с файлами заключается в записи и считывании элементов этой последовательности. Для того, чтобы указать, с каким элементом файла производятся операции, существует понятие указателя на доступный элемент файла.
Пример. Приведем шаблон программы для записи данных в файл.Program Writing;
Var
FileName : string; {строка, содержащая имя файла}
FVar : file of byte; {переменная файлового типа}
Index : byte;
Begin
write ('Введите имя файла ');{предложение ввести имя файла}
readln (FileName);{ввод имени файла}
assign (FVar, FileName);{связь имени файла и переменной}
rewrite (FVar);{открытие файла для записи}
for Index := 0 to 99 do {цикл для расчетов и вывода данных в файл}
write (FVar,Index);{запись в файл FVar величины Index}
close (FVar); {закрытие файла}
End.
Примечание. В цикле могут быть вычислительные процедуры для получения данных, выводимых в файл. Мы, для простоты, записали в файл счетчик цикла.
Внимание! Следует запомнить, что процедура rewrite обнулит файл, если файл с таким именем уже есть в рабочем каталоге, поэтому при выборе имен файлов соблюдайте осторожность.
Задание 1. Наберите предложенную для рассмотрения выше программу и дополните ее выводом на экран элементов файла (воспользуйтесь процедурой считывания из файла read и вывода write). Результат покажите учителю для оценки.
Задание 2. Создайте программу записи и чтения типизированного файла типа string.
Примеры решения задач
Рассмотрите примеры решения задач. Наберите тексты программ, проверьте их действие. Обратите внимание на комментарий. Выполните задания к задачам.
Задача 1. Дан файл, элементами которого являются целые числа. Найти среднее арифметическое элементов файла.
В примере решается задача считывание элементов из файла, их суммирование и нахождение среднего арифметического. Предполагается, что типизированный файл уже создан.
Задание. Дополните содержание текста задачи созданием типизированного файла file.dat. Добавленные строчки программы прокомментируйте.Program Srednee;
Uses
Crt;
Var
Kol,
Element,{переменная для хранения очередного элемента файла}
Summa {переменная для хранения суммы элементов файла}
:integer;
f : file of integer;
SrAriph : real
Begin
ClrScr;
assign(f,'file.dat');{связываем файловую переменную f с физическим файлом file.dat}
reset(f);{открываем файл для чтения}
Summa :=0;{обнуление суммы}
while not Еof(f) do{просматриваем файл до конца}
begin
read(f,Element);{считываем из файла очередной элемент в переменную Element}
Inc(Kol);{увеличиваем счетчик количества элементов файла}
Inc(Summa,Element);{увеличиваем переменную Summa на Element}
write('Среднее арифметическое элементов файла равно ',SrAriph:5:2);
close(f);{закрываем файл}
readln;
End.
Задача 2. Наберите на компьютере и рассмотрите текст программы, сформулируйте решаемую в ней задачу, дополните необходимыми операторами и комментарием. Покажите результат учителю для оценки.Program FileString;
Uses
Crt;
Var
f, g : file of string;
str1, str : string;
i : integer;
Begin
ClrScr;
assign(f,'f');
rewrite(f);
assign(g,'g');
rewrite(g);
repeat
readln(str);
write(f,str);
for i:=length(str) downto 1 do
str1:=str1+str[i];
write(g,str1);
str1:='';
until str='';
close(f);
close(g);
assign(f,'f');
reset(f);
assign(g,'g');
reset(g);
while not eof(f) do
begin
read(f,str);
writeln(str);
end;
while not eof(g) do
begin
read(g,str);
writeln(str);
end;
close(f);
close(g);
readln;
End.
Задача 3. Создать типизированный файл, содержащий информацию о работниках института.
выводом фамилий работников, начинающихся с заданной пользователем буквы;
выводом фамилий работников, у которых оклад больше заданного пользователем числа;
выводом фамилий работников предпенсионного возраста.Program TipRecord;
Uses
Crt;
Type
Dann=record
stag : byte;
Surname, WorkName : string;
Oklad, Year : integer;
End;
Var
Spisok : file of Dann; {файл типа записи Dann}
Man : Dann; {переменная типа записи Dann для работы с файлом}
Name : string[12]; {строка для хранения имени физического файла}
Procedure VvodZap (Nomer : integer);
Begin
with Man do
begin
writeln('Введите данные ',Nomer,'-го работника');
write('Фамилия: ');
readln(Surname);
write('Год рождения:');
readln(Уear);
write('Стаж работы:');
readln(stag);
writeln('Должность:');
readln(WorkName);
write('Оклад');
readln(oklad);
write(Spisok ,Man); {записать в файл созданный элемент Man}
end;
End;
Procedure FileVvod;
Var
i, count : Integer;
Begin
write('Введите имя файла данных:');
readln(Name); {имя физического файла}
assign(Spisok ,Name); {связываем файловую переменную с файлом}
rewrite(Spisok ); {открываем файл для записи}
write('Введите количество работников:');
readln(count);
for i:=1 to count do
VvodZap(i); {вызов процедуры ввода очередной информации в файл}
close(Spisok ); {закрываем файл}
readln;
End;
Begin
ClrScr;
FileVvod;
readLn;
End.
Вопрос36. Текстовые файлы, их описание и основные отличия от типизированных файлов.
Наряду с описанными типами файлов Pascal имеет средства взаимодействия с файлами несколько иной структуры-так называемыми текстовыми файлами. Введение текстовых файлов несколько нарушает стройность языка, однако позволяет использовать Pascal при программировании широкого класса задач, имеющих нечисловой характер и связанных с обработкой текстовой информации.
Во многих версиях языка допускается хранение файлов на диске как символьных данных. При считывании файла в оперативную память машины символы файла преобразуются в тот тип данных, который объявлен в программе. Файлы символьных данных называются текстовыми файлами. Текстовые файлы имеют тип text.
Структура текстовых файлов отличается от структуры обычных файлов (которые представляют из себя линейную последовательность элементов одного типа) тем, что содержимое текстового файла рассматривается как последовательность строк переменной длины, разделённых специальной комбинацией, называемой "конец строки". Как правило, эта комбинация строится из управляющего кода "перевода каретки" (CR, Carriage Return, символ #13), за которым, возможно, следует управляющий код "перевод строки" (LF, Line Feed, символ #10). Признаком конца строки считается нажатие клавиши ввода.
Текстовый файл завершается специальным кодом "конец файла" (символ #26). В большинстве случаев знание конкретной кодировки управляющих символов не обязательно ввиду наличия файловых операций, автоматически учитывающих эти символы.
Таким образом, текстовый файл структурно несколько похож на "файл из байтов" (file of byte) с той разницей, что в нем, помимо содержательной информации, встречаются символы специального назначения.
Его можно схематически представить в следующем виде:
Описанная структура текстовых файлов хорошо согласуется с интуитивно понимаемым построением текстовой информации и полностью совпадает со стандартной структурой текстов, принятой в MS-DOS, используемой во многих текстовых редакторах, понимаемой компиляторами с языков программирования и т.д.
С каждым файлом на диске должна быть связана файловая переменная, которая описывается в соответствии с типом файла на диске. Представителем же текстового файла в Pascal-программе является переменная файлового типа, которая должна быть описана с указанием стандартного типа text:Var
TextFile : text;
Примечание. Слово text не является зарезервированным словом, а считается идентификатором стандартного типа, наряду с идентификаторами integer, real и т.д.
Обращение к файлу в дальнейшем идёт через файловую переменную.
Далее доступ к файлу требуется открыть. Открыть любой файл можно на чтение и на запись. Для этого существуют процедуры reset, rewrite.
К примеру, пусть на диске создан текстовой файл text.txt.
Для Turbo Pascal описание и связывание файловой переменной f с файлом text.txt, будет выглядеть так :Var
f: text;
Begin
assign(f, 'd:\tp7\bin\text.txt'); {Полный путь до файла }
reset(f);{Открыть на чтение]
. . .
End.
assign([файл. пер. ], [полный путь до файла на диске]) -связывает файл на диске с файловой переменной f типа текст.
Примечание. Процедура assign не должна использоваться для открытого файла.
Когда имя файла на диске не указывается, то параметр f оказывается связанным со стандартным вводом/выводом. Если присвоено пустое имя, то после обращения к reset(f) f будет указывать на стандартный файл ввода, а после обращения к rewrite(f) f будет указывать на стандартный файл вывода.
reset([ файловая переменная ]) -открывает файл на чтение.
Ввод-вывод для текстовых файлов подчиняется тем же общим правилам, что и для обычных типизированных файлов; однако имеется несколько важных особенностей.
Во-первых, для одного текстового файла нельзя одновременно производить операции и ввода, и вывода. Это означает, что после открытия текстового файла процедурой reset возможно только чтение информации из файла, после процедуры rewrite