Лекция 20: Структурный тип - Файл.

End

End

IMPLEMENTATION

INTERFACE

Else

If line(a,b,c) then

Implementation

procedure rpoint;

begin x[1]:=random(100)/10;x[2]:=random(90)/10 end{rpoint};

procedure r;

begin d:=sqrt(sqr(x[1])+sqr(x[2])) end {r};

function dist;

begin dist:=sqrt(sqr(x[1]-y[1]) + sqr(x[2]-y[2])) end {dist};

function line;

begin line:=false;if (dist(x,y)=dist(x,z)+dist(y,z)) then line:=true;

if (dist(x,z)=dist(x,y)+dist(y,z)) then line:=true;

if (dist(z,y)=dist(x,z)+dist(x,z)) then line:=true;

end {line};

begin randomize;

END {points}.

program test_points; {Тест модуля points}

uses points;

var a,b,c:point;s:string[1];ra,rb,rc:real;

begin repeat writeln('Генерация точек a,b,c:');

rpoint(a);rpoint(b);rpoint(c);

writeln('a[1] a[2] b[1] b[2] c[1] c[2] ');

writeln(a[1]:2:2,' ',a[2]:2:2,' ',b[1]:2:2,' ',b[2]:2:2,' ',c[1]:2:2,' ',c[2]:2:2);

writeln('Расстояния от начала координат:');r(a,ra);r(b,rb);r(c,rc);

writeln('ra=',ra:2:2,' rb=',rb:2:2, ' rc=',rc:2:2);

writeln('Расстояния между точками:');

writeln('dist(a,b)=',dist(a,b):2:2);

writeln('dist(b,c)=',dist(b,c):2:2);

writeln('dist(a,c)=',dist(a,c):2:2);

writeln('line(a,b,c)=true {Точки а,в,с -лежат на одной прямой}')

writeln('line(a,b,c)=false {Точки а,в,с -не лежат на одной прямой}');

a:=b; writeln('a:=b; dist(a,b)=',dist(a,b):2:2);

if line(a,b,c) then writeln(' line(a,b,c)=true');readln(s);

until s=' ';

end {test_points}.

 

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

UNIT convert; {Преобразование целого числа в строку - название числа}

type array_s =array[1..5] of string;

procedure conv_int(int:string;var s_int:array_s);

procedure conv_int(int:string;var s_int:array_s);

type string3 =string[3];

var k:byte;{длина числа} j:byte;{параметр}

trd:array[1..5] of string3;{массив строк-триад}

function s_trd(t:string3;numt:byte):string;{перевод в название триады}

const d:array[2..5] of string =('тысяч','миллион','миллиард','триллион');

dig:array['1'..'9'] of string= ('один','два','три','четыре','пять','шесть','семь','восемь','девять');

var c:char;{переводимая цифра} j:byte; m:array[2..5] of string;

str1,str2,str3:string;{строки-названия цифр триады}

begin for j:=2 to 5 do m[j]:=d[j];

if t<>'000' then begin

c:=t[3];case c of '0':str3:='' else str3:=dig[c] end;

c:=t[2];case c of '0':str2:='';

'1':begin case t[3] of

'0':str2:='десять ';

'2':str2:='двенадцать ';

'3':str2:='тринадцать '

else str2:=copy(str3,1,length(str3)-1) +'надцать ';

end; if str2<>'' then str3:='';

end;

'2','3':str2:=dig[c]+'дцать ';

'4':str2:='сорок ';

'9':str2:='девяносто ' else str2:=dig[c]+'десят ';

end; c:=t[1];case c of '0':str1:='';

'1':str1:='сто ';

'2':str1:='двести ';

'3'..'4':str1:=dig[c]+'ста ';

'5'..'9':str1:=dig[c]+'сот ';

end;

if(numt=2)and(str3<>'') then case t[3] of '2'..'4':

begin if str3 ='два' then str3:='две ';m[2]:=m[2]+'и' end;

'1':if str3 ='один' then

begin str3:='одна ';m[2]:=m[2]+'а' end;

end;

 

if(numt>2)and(str3<>'') then case t[3] of '2'..'4':m[numt]:=m[numt]+'а';

'0','5'..'9':m[numt]:=m[numt]+'ов';

else if numt>2 then m[numt]:=m[numt]+'ов';

if numt>1 then s_trd:=str1+str2+str3+' '+m[numt]

else s_trd:=str1+str2+str3;

else s_trd:='';

end{s_trd};

begin{conv_int} k:=length(int); if k<15 then

for j:=1 to 15-k do int:='0'+int;

if k>15 then halt ;

for j:=1 to 5 do

trd[j]:=int[15-(j-1)*3-2]+int[15-(j-1)*3-1]+int[15-(j-1)*3];

for j:=5 downto 1 do

s_int[6-j]:=s_trd(trd[j], j);

end{conv_int};

END {convert}.

program demo_conv_int; {Тест модуля convert}

uses convert;

var j:byte;i:string;str_i:array_s;{type array_s=array[1..5] of string}

begin repeat write('Введите целое число:');readln(i);

conv_int(i,str_i);for j:=1 to 5 do{ Построчный вывод названия числа i}

if str_i[j]<>'' then writeln(str_i[j]); readln(i);

until i=''; {Выход из цикла при нажатии enter}

end{dem_conv}.

 

5. Использование модулей в программах.

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

Модули, предназначенные для использования в любых программах, естественно считать стандартными модулями. Они включаются в состав системы программирования как её неотъемлемая часть.

В Турбо Паскале имеется целая группа стандартных модулей: system, dos, crt, printer, overlay, graph и др. Первые пять этих модулей объединены в библиотечный файл со стандартным именем turbo.tpl. Этот файл является одним из обязательных для работы с системой Турбо Паскаль.

Основным стандартным модулем библиотеки turbo.tpl является модуль system, в котором сосредоточены процедуры и функции для всех стандартных типов данных (таких как integer, real, string и др.), а также многие подпрограммы общего назначения. Модуль system является единственным стандартным модулем, не требующим для работы с ним uses-описания (он подключен к любой программе по умолчанию). Все остальные стандартные модули из tubo.tpl становятся доступными только после их uses-описания в программе, как и для всех других модулей.

Стандартный модуль dos содержит средства доступа к операционной системе MS DOS, осуществляя интерфейс между системой Турбо Паскаль и MS DOS.

Стандартный модуль printer - самый простой из стандартных модулей. Он содержит лишь переменную Lst , осуществляющую связь с принтером для процедур вывода write и writeln.

Стандартный модуль overlay обеспечивает организацию оверлейных программ - программ с перекрытием в оперативной памяти (т.е. позволяющих использовать программы, размер которых превышает объем доступной оперативной памяти).

Особое место в Турбо Паскале занимают стандартные модули CRT и GRAPH. Модуль CRT содержит средства для управления экраном дисплея в текстовом режиме, а также ввода информации с клавиатуры, управления звуком и задержкой. Модуль GRAPH содержит несколько десятков процедур и функций для управления экраном дисплея в графическом режиме. Этот модуль работает совместно с графическими драйверами дисплея (файлами с расширением bgi), обеспечивая создание графических программ практически для всех типов адаптеров SVGA, VGA, EGA и других. Модули CRT и GRAPH ниже будут рассмотрены подробнее.

 

6. Стандартный модуль СRT.

Некоторые простейшие средства управления экраном из модуля CRT были уже рассмотрены ранее (при изучении простых операторов Турбо Паскаля). Здесь мы более подробно рассмотрим средства модуля CRT в целом.

В текстовом режиме экран рассматривается как матрица из строк и столбов, в каждую позицию которой может быть помещен символ из кодовой таблицы ASCII. Координаты экрана измеряются от верхнего левого угла, имеющего координаты (1,1), и возрастают слева направо и сверху вниз. Число строк и столбцов зависит от режима экрана (обычный режим - 25 строк и 80 столбцов). Позиция экрана характеризуется также визуальными свойствами: цветом фона, цветом линий символа и яркостью (нормальная, низкая, высокая).

Модуль CRT содержит ряд процедур, функций, константы цветов, режимов экрана и некоторые переменные. Все средства модуля CRT можно разделить на несколько групп: установки режима экрана, ввода с клавиатуры, управления курсором, управления окном, управления цветом и яркостью, управления звуком.

Установка режима экрана: процедура TextMode(mode:word) устанавливающая режим (число строк и столбцов экрана, монохромный или цветной режим) в соответствии с константами режима. Константа последнего установленного режима сохраняется в стандартной переменной lastmode. К этой группе относится также процедура AssignCrt(var F:text), осуществляющая связь с файловой переменной F клавиатуры для ввода, либо экран для вывода текста.

Ввод с клавиатуры: функции без аргументов KeyPressed (с результатом булевского типа) и ReadKey (с результатом типа char). Функция KeyPressed фиксирует сам факт нажатия на любую клавишу, возвращая true, если клавиша была нажата и false - в противном случае. Функция ReadKey осуществляет "слепое чтение" кода нажатой клавиши, приостанавливая выполнение программы до нажатия клавиши и возвращая в качестве результата код клавиши (без отображения его на экране). Это более гибкое средство ввода с клавиатуры, чем операторы read и readln.

Управление курсором: процедуры GotoXY(x,y:byte), CtrlEol, DelLine, InsLine; функции без параметров whereX, whereY. Эти процедуры позволяют установить курсор в позицию (x,y); удалить символы от курсора до конца строки; удалить текущую строку, сдвинув вверх все остальные строки и, очистив нижнюю строку; вставить пустую строку в позицию курсора. Функции whereX, whereY позволяют определить текущее положение курсора на экране (или в окне экрана) и возвращают позицию курсора как целое типа byte.

Управление цветом и яркостью: процедуры TextBackGround(color:byte), TextColor(color:byte), ClrScr, NormVideo, HighVideo, LowVideo. Первые три процедуры уже были описаны раннее среди простых средств управления экраном, а остальные предназначены для установки нормальной, высокой или низкой яркости символов и относятся к последующему выводу символов на экран.

Управление окнами: процедура window(x1,y1,x2,y2:byte) предназначена для установки окна на экране и была уже описана ранее. В дополнении к ней в модуле CRT имеются переменные windmin и windmax типа word, в которых, хранятся координаты текущего окна (верхнего левого и нижнего угла).

Управление звуком: процедуры sound(f:word), nosound, delay(d:word). Эти процедуры соответственно включают генератор звука с частотой f, выключают генератор звука, устанавливают задержку (приостановку работы программы) на d миллисекунд. Для иллюстрации использования средств модуля CRT приведем пример программы, реализующей "бегущую строку":

program animal_string_m;

{Программа демонстрации "бегущей" строки}

uses CRT;

var str:string; {Вводимая строка}

x,y,x0,x1:byte;j,k,r:byte;

procedure write_anim(s:string);

{ Анимированный посимвольный вывод строки }

var i:byte;

begin for i:=1 to length(s) do begin write(s[i]);delay(300) end;

end{write_anim};

BEGIN textbackground(cyan);textcolor(white);clrscr;

write_anim(' Программа "бегущей" строки');

repeat repeat window(25,10,55,11);textbackground(green);

textcolor(black);clrscr;

write_anim('Введите строку:');writeln;x:=whereX;y:=whereY;

Lowvideo;k:=0;gotoXY(x,y);readln(str);r:=length(str);

for j:=1 to r do if str[j]=' ' then inc(k);

until k<r;

gotoXY(x,y);Highvideo;write_anim(str);

x0:=Lo(windmin);x1:=Lo(windmax); r:=x1-x0-r;

{ Имитация "бегущей строки"}

for j:=1 to r do{ Сдвиг строки вправо на один символ}

begin str:=' '+str;gotoXY(x,y);write(str);delay(300) end

until readkey=#13;

END { animal_string_m}.

7. Стандартный модуль GRAPH.

Модуль GRAPH - библиотека подпрограмм работы с графическим режимом экрана. В графическом режиме экран рассматривается как совокупность точек (пикселей), яркостью и цветом которых можно управлять, получая то или иное графическое изображение. В модуле GRAPH имеются около 80 подпрограмм управления графическим экраном, обеспечивающие многие потребности графических программ. У нас нет возможности детально останавливаться на этих подпрограммах, поэтому ограничимся общей характеристикой средств данного модуля и простым примером графической программы, использующей модуль GRAPH.

 

Графический экран состоит из точек-пикселей, образующих растр. Для адресации пикселя используется координатная сетка, ведущая свой отсчёт от верхнего левого угла, имеющего координаты (0,0), и увеличивающая значения координат слева направо и сверху вниз. Для установки графического режима предусмотрена процедура InitGraph, а для возврата в текстовый режим - CloseGraph. На экране можно создавать графические окна (процедурой SetViewPort), ограничивающие графический вывод границами окна.

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

Имеются средства вывода текста на графический экран с помощью специально предусмотренных шрифтов (матричных и штриховых). Для использования штриховых шрифтов необходимы соответствующие шрифтовые файлы (с расширением chr).

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

Для иллюстрации работы с модулем GRAPH приведем небольшую программу формирования и вывода на графический экран изображения Российского флага:

program russian_flag;

{Формирование изображения Российского флага на графическом экране}

uses Graph,CRT;

var path:string;driver,mode,r,j,i:integer;c:word;

begin {начальная установка графического режима}

clrscr;driver:=detect;mode:=VGAHi;InitGraph(driver,mode,'');

{полукруг на голубом фоне}

setbkcolor(cyan);r:=99;arc(319,239,0,180,r);

{рисование флагштока}

moveto(319-r,239);lineto(319+r,239);delay(1000);

{наполнение цветом полукруга и флагштока}

setfillstyle(solidfill,green);floodfill(300,200,white);

{рисование трехцветного флага}

moveto(319,239-r);lineto(319,5);c:=white;

for j:=1 to 3 do begin setfillstyle(solidfill,c);

bar(319,5+(j-1)*33,319+2*r,5+j*33);

c:=(c+3) mod 17;delay(1000)

end;readln

end{ russian_flag}.

1. Концепция файла в Паскале.

2. Виды файлов и описание файлов в Паскале.

3. Открытие файлов.

4. Стандартные процедуры и функции работы с файлами.

5. Текстовые файлы .

6. Особенности работы с типизированными файлами.

 

1. Концепция файла в Паскале.

Понятие файла является одним из центральных в информатике. Файл - аналог давно существующего в библиотечном деле понятия картотеки (английское слово file и означает, собственно, картотеку). Как и для картотеки, файл - последовательность некоторых записей (компонент), размещаемых на внешнем носителе. Файл представляет самостоятельный объект с точки зрения доступа к нему. Введение понятия файл совершенно необходимо для планирования размещения информации во внешней памяти компьютера (дисках, лентах), а также на экране дисплея, листах на принтере и других внешних устройствах.

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

Для последовательных файлов (типа картотеки) невозможен непосредственный доступ к любой записи: доступ осуществляется только через предыдущие записи. Например, чтобы прочитать 15-ю запись, необходимо прочесть 1,2, ...14-ю запись, даже если они ненужны. Некоторые типы внешних устройств (такие как клавиатура, листы принтера) допускают только последовательный доступ к записям информации.

Файлы с прямым доступом позволяют получить непосредственный (прямой) доступ к любой записи. Примерами файлов с прямым доступом являются дисковые файлы (файлы на винчестере, флоппи-диске или на CD). Дисковые файлы, разумеется, могут быть организованы и как последовательные файлы.

В языке Паскаль файл - структурный тип, представляющий последовательность компонентов-записей любого типа Паскаля (кроме типа файл) и размещаемых на внешнем носителе. Размещение на внешнем носителе гарантирует сохранение файла неизменным, после завершения программы. Файл - единственная структура данных Паскаля, которая сохраняет свою информацию после завершения программы. Файл может размещаться на любом внешнем устройстве компьютера и представляет для программиста логическую структуру, инвариантную к конкретному физическому носителю. Кроме того, файл - типичная динамическая структура, т.к. размер файла может неограничено изменяться в процессе выполнения программы обработки файла (если используются процедуры записи информации в файл).

 

2. Виды файлов и описание файлов в Паскале.

В зависимости от типа записи файлы классифицируют на три вида:

-Типизированные файлы: все записи файла имеют один и тот же тип.

-Текстовые файлы: все записи файла имеют тип string.

- Нетипизированные файлы: тип записи файла никак не фиксирован.

Описание файла зависит от его вида:

Текстовый файл - стандартный тип файла со стандартным именем text.

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

type <имя типа> = file of <тип записи>;

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

type <имя типа> = file ;

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

Например: type reestr = file of form;

form= record name:string[20]; regN:integer;date:string[16] end;

var: R1:reestr; T:text;

Здесь: reestr - типизированный файл записей типа form; R1 - файловая переменная типа reestr; Т - файловая переменная типа text (текстовый файл).

Любой программе доступны также две стандартные файловые переменные: input - файл чтения с клавиатуры, output - файл вывода на экран дисплея.

 

3. Открытие файлов.

В отличие от других типов Паскаля, для работы с файловой переменной (доступа к файлу) необходимо выполнить открытие файла - некоторые подготовительные действия, обусловленные спецификой файлового типа данных. Подготовительные действия по открытию файла включают:

- связывание файловой переменной с именем конкретного файла на внешнем устройстве;

- инициализация (начальная установка) файла в соответствии с характером последующих операций с файлом;

В Паскале каждое из этих действий выполняется специальной процедурой.

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

assign(<имя файловой переменной>,<имя файла или логического устройства>);

Если второй параметр этой процедуры - пустая строка, то имеется в виду стандартный файл input или output. Во всех других случаях второй параметр - имя файла, соответствующее имени в MS DOS (имя файла содержит явно или неявно путь к файлу), либо имя логического устройства.

Имена логических устройств - это специальные имена, принятые в Турбо Паскале для доступа к стандартным внешним устройствам: con - консоль (клавиатура или экран монитора), prn - принтер (если принтеров несколько, то они именуются LPT1, LPT2 и т.д.), aux - коммуникационный канал, nul - "пустое" устройство.

Инициализация файла указывает направление передачи данных между оперативной памятью и файлом. В Паскале предусмотрены 3 стандартные процедуры инициализации файла: для чтения, для записи (создания файла), для добавления записей в существующий файл. Записи файла нумеруются, начиная с 0.

Инициализация файла для чтения - установка файла для чтения 0-записи:

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

Для текстовых файлов, открытых процедурой reset, недопустимо использовать процедуры вывода в файл (write, writeln), а для типизированных файлов - допустимо использовать как процедуры read (для чтения записи файла) и write (для обновления записей).

Инициализация файла для создания файла:

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

Эта процедура создает новый пустой файл с именем, указанным ранее в процедуре связывания assign (если имя файла совпадает с ранее существующим файлом, то он стирается). Новый файл подготовлен к добавлению в него информации процедурой write (для типизированных файлов) или write, writeln (для текстовых файлов).

Инициализация файла для добавления записей в конец имеющегося файла:

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

Эта процедура устанавливает файл на конец последней записи и открывает доступ процедурам write, writeln для расширения файла новыми строками. Она применима только к текстовым файлам (для типизированных файлов её функции можно выполнять при открытии файла процедурой reset). Заметим, что для текстовых файлов в Паскале не предусмотрено средств обновления существующих строк-записей.

 

4. Стандартные процедуры и функции работы с файлами.

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

Процедура close (<файловая переменная>);

Эта процедура закрывает файл, сохраняя связь, установленную соответствующей процедурой assign. Особенно важна процедура close для режима добавления записей в файл: при её отсутствии возможны ситуации, когда информация, записываемая в файл, "застрянет" в буфере, в котором накапливаются записи. При нормальном завершении программы функции процедуры close выполняются автоматически (даже при её отсутствии в программе) для всех открытых для чтения файлов.

Процедура erase (<файловая переменная>);

Эта процедура уничтожает файл, ей должна предшествовать процедура close.

Процедура read([<файловая переменная>],<список переменных>);

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

Процедура write([<файловая переменная>],<список выражений>);

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

Функция eof(<файловая переменная>);

Логическая функция, определяющая конец файла. Её значение true, если достигнут конец файла и false в противном случае.

Функция IOResult.

Вырабатывает признак последней операции ввода-вывода. Если операция завершилась успешно, IOResult=0, если неуспешно - IOResult <>0. Эта функция доступна только при отключенном автоконтроле ошибок ввода-вывода (директивой компилятора {$I-}). Функция IOResult часто используется для контроля существования файла при его открытии (это будет проиллюстрировано в последующих примерах программ).

 

5. Текстовые файлы.

Это специальный вид файлов, широко распространенный для хранения и обработки текстовой информации. В таких файлах удобно хранить различные документы, тексты программ на Турбо Паскале, тексты на естественных языках. Текст, при этом, понимается как последовательность строк символов. Строки (как тип string) могут иметь переменную длину (до 255 символов). Каждая строка файла типа text заканчивается специальным признаком eoln (end of line -конец строки), который кодируется последовательностью кодов ASCII #13 и #10. В конце файла (последней строки) дополнительно указывается признак eof (end of file - конец файла), кодируемый #26.

Логические функции еoln и eof предназначены для проверки признаков конца строки и конца файла соответственно и вырабатывают true при их обнаружении.

Для обращения к строкам-записям текстового файла используются стандартные процедуры read, readln и write, writeln. Особенностями их для текстовых файлов является то, что переменные списка ввода и выражения списка вывода могут быть любыми из типов: числа (целые или вещественные типы), символы (тип char), строки (тип string). Эти типы автоматически преобразуются в тип записи - строку string.

При работе со стандартным файлом input вводимые с клавиатуры символы запоминаются в буфере, содержимое которого передается процедурам read, readln только после нажатия клавиши Enter (что позволяет редактировать данные при вводе). Кроме того, ввод сопровождается эхо-повтором вводимых символов на экране.

При работе со стандартным файлом output вывод на экран представляет непрерывную последовательность строк и после вывода очередной строки автоматически обеспечивается сдвиг вверх на одну строку. Операторы readln и writeln отличаются от read и write лишь переходом к следующей строке ввода или вывода.

 

6. Особенности работы с типизированными файлами.

Типизированные файлы отличаются постоянной длиной своих компонентов-записей, что даёт возможность прямого доступа к каждой записи по её номеру. Наиболее часто этот вид файлов применяется для хранения и обработки структурированной информации, когда компонентом файла является тип Запись (record).

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

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

seek (<файловая переменная>,<N записи>); - установка файла на запись N.

Для типизированных файлов также доступны функции (типа longint):

filesize (<файловая переменная>), определяющая число записей в файле,

filepos(<файловая переменная>), определяющая номер следующей записи.