Основы программирования на языке Паскаль
if nomer=9999 then begin Close(bf);Exit end;
writeln('ввести имя автора'); readln(avtor);
writeln('ввести название книги'); readln(nazv);
writeln('ввести значение индекса'); readln(index);
write(bf,rb); end;end;
BEGIN { основная программа }
Org; Obr; Rash; Obr; readln;
END.
При создании больших программ их части удобно создавать в виде отдельных файлов (объектов), которые затем с помощью директивы компилятора {$i...} можно объединить в одну программу. Это удобно еще и тем, что несколько программистов могут создавать различные программы, что в несколько раз может ускорить процесс их создания.
Создадим ту же программу, что и Prim 47, только пообъектно, тогда процедуру Org запишем в C:\TURBO\Org1.pas, процедуру Obr - в C:\TURBO\Orb1.pas, процедуру Rash - в C:\TURBO\Rash1.pas, а вызывающую (основную программу - в C:\TURBO\Prim. 48, в которой предусмотрим подключение объектов - процедур Org, Obr, Rash к основной программе через директивы компилятора $i.
procedure Org1;
begin
assign(bf,'C:\TURBO\bibl.dos');
Rewrite(bf);
with rb do
while True do
begin writeln('ввести номер книги');
readln(nomer);
if nomer=9999 then
begin close(bf); Exit;
end;
writeln('ввести имя автора');
readln(avtor);
writeln('ввести название книги');
readln(nazv);
writeln('ввести название индекса');
readln(index);
write(bf,rb);
end;
end;
procedure Obr1;
begin
Assign(bf,'C:\TURBO\bibl.dos');
Reset(bf);
with rb do
while not eof(bf) do
Begin read(bf,rb);
writeln(nomer:5,avtor:16,Nazv:10,index:6);
end;
Close(bf);
writeln('нажмите enter'); readln;
end;
procedure Rash1;
begin Assign(bf,'C:\TURBO\bibl.dos');
Reset(bf);
Seek(bf,Filesize(bf));
with rb do
while True do
begin writeln('введите номер'); readln(nomer);
if nomer=9999 then begin Close(bf);exit end;
writeln('введите имя автора'); readln(avtor);
writeln('введите название книги'); readln(nazv);
writeln('введите значение индекса'); readln(index);
write(bf,rb);
end;end;
Работу построим в режиме меню.
Program Prim48;
label M;
type books=record
nomer:integer;
avtor:string[16];
nazv:string[30];
index:integer; end;
Var bf:file of books;
rb:books; regim:byte;
{$i C:\TURBO\Org1.pas}
{$i C:\TURBO\Obr1.pas}
{$i C:\TURBO\Rash1.pas}
BEGIN
M: writeln('введите режим работы');
writeln('1 - создание, 2 - обработка',
'3 - расширение, 4 - выход');
readln(regim);
case regim of
1:Org1;
2:Obr1;
3:Rash1;
4:Exit; else writeln('неправильно задан режим'); end;
goto M;
END.
Для обеспечения работы с различными именами файлов имя файла вначале запрашивается, а затем передается в процедуры. Таким образом, мы можем создавать несколько файлов, содержащих данные о книгах, их обрабатывать, расширять и т.п.
Program Prim49;
label M1,M2 ;
type books=record
nomer:integer;
avtor:string[16];
nazv:string[30];
index:integer; end;
Var bf:file of books;
rb:books; regim:byte; si:char; fl:string;
{$i C:\TURBO\Org.pas}
{$i C:\TURBO\Obr.pas}
{$i C:\TURBO\Rash.pas}
BEGIN
M1: writeln('где будет храниться файл? диск:\каталог\имя'),
readln(fl);
M2: writeln('введите режим работы');
writeln('1 - создание, 2 - обработка',
'3 - расширение, 4 - выход');
readln(regim);
case regim of
1:Org;
2:Obr;
3:Rash;
4:begin writeln('будем ещё работать с файлами? - "Y"');
writeln('или конец работы - любая клавиша');
readln(si);
if (si='Y')or(si='y') then goto M1 else HALT; end;
else begin writeln('неправильно задан режим');
goto M2; end; end; goto M2;
END.
Procedure Org2;
begin
assign(bf, fl);
Rewrite(bf);
with rb do
while True do
begin writeln('введите номер книги');
readln(nomer);
if nomer=9999 then
begin close(bf); Exit end;
writeln('введите имя автора');
readln(avtor);
writeln('введите название книги');
readln(nazv);
writeln('введите значение индекса');
readln(index);
write(bf,rb);
end; end;
Procedure Obr2;
begin
Assign(bf, fl);
Reset(bf);
with rb do
while not Eof(bf) do
begin read(bf, rb);
writeln(nomer:5,avtor:16,Nazv:10,index:6);
end; Close(bf);
end;
Procedure Rash2;
begin assign(bf, fl);
Reset(bf);
Seek(bf,Filesize(bf));
with rb do
while True do
begin writeln('введите номер'); readln(nomer);
if nomer=9999 then begin Close(bf);Exit end;
writeln('введите имя автора'); readln(avtor);
writeln('введите название книги'); readln(nazv);
writeln('введите значение индекса'); readln(index);
write(bf,rb);
end;end;
10.5. Файлы произвольного доступа
Файлы произвольного доступа используются при наличии зависимости значения какого-либо поля компоненты от ее порядкового номера в файле. Порядковый номер компоненты иногда называют ключом компоненты файла.
Организовать файл произвольного доступа можно двумя способами:
Создать последовательный файл и обращаться к компонентам по порядковому номеру, трактуя последовательный файл как файл прямого доступа.
Создать файл фиктивных (с пустыми полями) компонент, затем загрузить его по ключу фактическими данными. этот способ - создание файла с фиктивными компонентами - называется форматизацией.
Пример. Форматировать файл произвольного доступа из 20 компонент c:\turbo\bibl.dos. Структура компонент такая же, как и в Prim 47-49. Оформим алгоритм в виде процедуры form, запишем ее в c:\turbo\form.pas.
Procedure form;
Begin writeln ('дайте имя форматизируемому файлу');
readln(filname);
assign(booksfile, filname);
rewrite(booksfile);
with recbooks do
Begin writeln ('на сколько записей форматировать файл?');
readln(razmer);
for i:=l to razmer do
Begin nomer:=i; avtor:=' '; index:=0; nazv:=' ';
write ( books file, recbooks)
end; end; writeln(фopматизация ',razmer,' запись выполнена');
close(booksflle); end;
Напишем процедуру загрузки (procedure zagruz), которая будет заменять поля фиктивных записей реальными значениями, и запишем ее в c:\turbo\zagruz.pas;
procedure zagruz; Begin writeln('дать имя загружаемого по ключу файла');
readln(filname);
assign(booksfile,filname); reset(booksfile);
writeln('сколько записей будете вводить?'); readln(k);
with recbooks do
Begin for i:=1 to k do
Begin writeln('введите номер'); readln(nomer);
writeln('введите имя автора'); readln(avtor);
writeln('введите название книги'); readln(nazv);
writeln('введите индекс'); readln(index);
seek(booksfile,nomer-1); { номера компонент начинаются с 0 }
write(booksfile,recbooks); end; end;
close(booksfile); end;
Оформить процедуру прямого доступа по ключу к компонентам файла и выдачу их на экран монитора, записать ее в C:\TURBO\OBRAB.PAS;
Procedure Obrab;
Begin writeln('дайте имя файла'); readln(filname);
assign(booksfile,filname); reset(booksfile);
while true do
Begin writeln('укажите ключ обрабатываемой записи'); readln(k);
if k=9999 then Begin close(booksfile); exit; end;
seek(booksfile,k-1);
with recbooks do Begin read(booksfile,recbooks);
writeln(nomer:5,avtor:16,nazv:15,index:4);
end; end; end;
Написать процедуру корректировки файла произвольного доступа в которой будут предусмотрены режимы корректировки:
Замена всех полей компоненты.
Расширение файла в пределах отформатированного пространства.
все это делает процедура Кооr, записанная в c:\turbo\koor.pas.
Procedure Koor;
Var nevavtor:string[16]; nevnazv:string[30]; nevindex:integer;
Begin writeln('дайте имя файла'); readln(filname);
assign(booksfile,filname); reset(booksfile);
with recbooks do
Begin writeln('сколько записей будете корректировать?'); readln(k);
for i:=1 to k do
Begin writeln('дайте номер корректируемой записи'); readln(k1);
nevavtor:=' '; nevnazv:=' '; nevindex:=0;
writeln('введите имя автора'); readln(nevavtor);
writeln('введите название книги'); readln(nevnazv);
writeln('введите индекс'); readln(nevindex);
avtor:=nevavtor; nazv:=nevnazv; index:=nevindex;
seek(booksfile,k1-1); write(booksfile,recbooks);
end; end; close(booksfile); end;
В программе Prim 50, с помощью меню рассматриваются работа с файлами произвольного доступа во всех режимах; форматирование файла, его загрузка, обработка, корректировка. Здесь следует заметить, что программа универсальна в том смысле, что может работать с различными файлами.
Program Prim50;
Type books=record
nomer:integer; avtor:string[16];
nazv:string[30]; index:integer; end;
Var booksfile:file of books;
recbooks:books; razmer,k,k1,i,reg:integer;
filname:string[12];
{$i c:\turbo\form.pas}
{$i c:\turbo\zagruz.pas}
{$i c:\turbo\obrab.pas}
{$i c:\turbo\koor.pas}
Begin while true do
Begin writeln('укажите режим');
writeln('1: форматизация');
writeln('2: загрузка по ключу');
writeln('3: обработка по ключу');
writeln('4: корректировка');
writeln('5: выход из программы');
readln(reg);
case reg of 1:form; 2:zagruz; 3:obrab; 4:koor; 5:halt;
end;
end;
end.
10.6. Текстовые файлы
Компонентами текстовых файлов являются строки. Длина строки - 0-255 символов. Каждая строка завершается маркером строки, а файл - маркером конца файла. Для описания файловых переменных текстового типа используется зарезервированное слово text.
Var instrl, instr2: text;
dokulnent: text;
Для работы с текстовыми файлами используются упомянутые выше функции и процедуры assign, rewrite, reset, close, read, readln, write, writeln, seekeof, однако имеются и специфические функции и процедуры:
Append (fv) - открыть текстовый файл и установить указатель на маркер конца файла.
Eoln (fv) - возвратить true, если указатель файла достиг маркера конца строки, в противном случае, возвратить значения false.
Seekeoln(fv) - функция, аналогичная предыдущей, но указатель проходит все пробелы и знаки табуляции. возвращает true при достижении маркера конца строки.
Seekeof(fv) - возвращает true, если указатель файла находится на маркере конца файла.
Организация текстового файла производится по схеме:
1) объявляется файловая переменная текстового типа;
2) присваивается файлу имя (assign);
3) открывается файл (rewrite);
4) подготавливается строка - компонента для записи в файл;
5) записывается строка - компонента в файл (writeln);
6) повторяются п. 4, 5 столько раз, сколько нужно;
7) закрывается файл.
Доступ к компонентам текстового файла:
1) присвоить файлу имя (assign);
2) открыть файл для чтения (reset);
3) прочитать компоненту-строку (readln);
4) обработать компоненту-строку (например вывести на экран);
5) повторить п. 3, 4 столько раз, сколько нужно.
6) закрыть файл (close);
Расширение текстового файла производится путем добавления в конец файла компонент-строк:
1) присвоить имя файлу (assign);
2) установить маркер на конец файла (append);
3) подготовить строку для записи;
4) записать строку (writeln);
5) повторить нужное количество раз п. 3, 4.
6) закрыть файл (close).
Замечание. При записи файлов прямого и последовательного доступа, созданных пользователем, содержимое компонент упаковывается, и поэтому посмотреть их в vc или nc по f3 или f4 нельзя, а текстовый файл не упаковывается, и его можно просмотреть.
procedure sozdt;
Begin writeln('дайте имя создаваемому текстовому файлу');
readln(filename);
assign(stro,filename); rewrite(stro);
while true do
Begin writeln('напишите содержимое строки');
readln(s); if s='zzz' then {'zzz' - признак окончания ввода }
Begin close(stro); exit; end;
writeln(stro,s); end;end;
procedure obrt;
Begin writeln('дайте имя обрабатываемого файла');
; readln(filename);
assign(stro,filename); reset(stro);
repeat readln(stro,s); writeln(s);
until seekeof(stro); close(stro); exit; end;
procedure rasht;
Begin writeln('укажите имя корректируемого файла'); readln(filename);
assign(stro,filename); append(stro);
while true do
Begin writeln('введите строку'); readln(s);
if s='zzz' then Begin close(stro); exit; end;
writeln(stro,s); end; end;
Program Prim51;
Type dlina=string[60];
Var stro:text; s:dlina; reg:char; filename:string[12];
{$i c:\turbo\sozdt.pas}
{$i c:\turbo\obrt.pas}
{$i c:\turbo\rasht.pas}
Begin while true do
Begin writeln('укажите режим');
writeln('1: создание, 2: вывод на экран, 3: расширение, 4: выход');
readln(reg);
case reg of '1': sozdt;
'2': obrt;
'3': rasht;
'4': halt else writeln('повторите номер режима');
end;end;end.
11. Использование библиотеки CRT
Разработчики Турбо-Паскаля предусмотрели несколько подпрограмм, существенно увеличивающих возможности текстового ввода-вывода. Эти подпрограммы сосредоточены в библиотеке (модуле) CRT, входящей в комплект поставки Турбо-Паскаля. В модуль включены также процедуры sound, no sound, delay, позволяющие программировать звуковой генератор компьютера.
11.1. Программирование клавиатуры
Дополнительные возможности управления клавиатурой реализуются двумя функциями: keypressed и ReadKey.
Функция keypressed возвращает значение типа boolean, указывающее состояние буфера клавиатуры: false означает, что буфер пуст, а true - что в буфере есть хотя бы один символ, еще не прочитанный программой.
В реализуется так называемый асинхронный буферизованный ввод с клавиатуры. По мере нажатия на клавиши соответствующие коды помещаются в особый буфер, откуда они могут быть затем прочитаны программой. Стандартная длина буфера рассчитана на хранение до 16 кодов символов. Если программа достаточно долго не обращается к клавиатуре, а пользователь нажимает клавиши, буфер может оказаться переполненным. В этот момент раздается звуковой сигнал и «лишние» коды теряются. Чтение из буфера обеспечивается процедурами read/rеadln и функцией ReadKey. обращение к функции keypressed не задерживает исполнения программы: функция немедленно анализирует буфер и возвращает то или иное значение, не дожидаясь нажатия клавиши.
Функция ReadKey возвращает значение типа char. При обращении к этой функции анализируется буфер клавиатуры: если в нем есть хотя бы один не прочитанный символ, код этого символа берется из буфера и возвращается в качестве значения функции, в противном случае функция будет ожидать нажатия на любую клавишу. Ввод символа с помощью этой функции не сопровождается эхо-повтором и содержимое экрана не меняется. Например, в какой-то точке программы необходимо игнорировать все ранее нажатые клавиши, коды которых еще непрочитаны из буфера, т.е. необходимо очистить буфер. Этого можно достичь следующим способом:
Uses CRT;
Var
с; char;
Begin
while Keypressed do
c:== ReadKey;
. . . . .
end.
При использовании процедуры ReadKey следует учесть, что в клавиатурный буфер помещаются так называемые расширенные коды нажатых клавиш. Если нажимается любая алфавитно-цифровая клавиша, расширенный код совпадает с ASCII-кодом соответствующего символа. Например, если нажимается клавиша с латинской буквой «а» (в нижнем регистре), функция ReadKey возвращает значение chr(97), а если - «а» (в верхнем регистре) - значение chr(65). При нажатии функциональных клавиш F1...F10 (клавиш управления курсором), клавиш Ins, Home, Del, End, PgUp, PgDn в буфер помещается двухбайтовая последовательность: сначала символ #0, а затем расширенный код клавиши. Таким образом, значение #0, возвращаемое функцией ReadKey, используется исключительно для того, чтобы указать программе на генерацию расширенного кода. Получив это значение, программа должна еще раз обратиться к функции, чтобы прочитать расширенный код клавиши.
Следующая простая программа позволит определить расширенный код любой клавиши. Для завершения работы программы нужно нажать клавишу esc.
Uses CRT;
Var с: char;
Begin
repeat
c:= ReadKey;
if c< >#0 then
writeln (ord(c))
else
writeln ('0', ord (ReadKey):8)
until c=#27 {27 - расширенный код клавиши esc}
end.
Если вы воспользуетесь этой программой, то обнаружите, что нажатие на некоторые клавиши игнорируется функцией ReadKey. Это прежде всего так называемые сдвиговые клавиши - Shift, Ctrl, Alt. Сдвиговые клавиши в MS-DOS обычно используются для переключения регистров клавиатуры и нажимаются в сочетании с другими клавишами. Именно таким способом, например, различается ввод прописных и строчных букв. Кроме того, функция игнорирует переключающие клавиши Caps Lock, Num Lock, Scroll Lock.
в таблице приведены расширенные коды клавиш, возвращаемые функцией ord(ReadKey).
Расширенные коды клавиш
Таблица
Код
|
Клавиша или комбинация клавиш
|
Код
|
Клавиша или комбинация клавиш
|
|
первый байт
|
второй байт
|
|
первый байт
|
второй байт
|
|
|
Алфавитно-цифровые клавиши
|
|
8
|
-
|
backspace (забой)
|
9
|
-
|
tab (табуляция)
|
|
13
|
-
|
enter
|
32
|
-
|
пробел
|
|
33
|
-
|
!
|
34
|
-
|
«
|
|
35
|
-
|
#
|
36
|
-
|
$
|
|
37
|
-
|
%
|
38
|
-
|
&
|
|
39
|
-
|
"
|
40
|
-
|
(
|
|
41
|
-
|
)
|
42
|
-
|
*
|
|
43
|
-
|
+
|
44
|
-
|
,
|
|
45
|
-
|
-
|
46
|
-
|
.
|
|
47
|
-
|
/
|
48...57
|
-
|
0...9
|
|
58
|
-
|
:
|
59
|
-
|
;
|
|
60
|
-
|
<
|
61
|
-
|
=
|
|
52
|
-
|
>
|
63
|
-
|
?
|
|
64
|
-
|
@
|
65...90
|
-
|
A...Z
|
|
91
|
-
|
[
|
92
|
-
|
/
|
|
93
|
-
|
]
|
94
|
-
|
^
|
|
95
|
-
|
_
|
96
|
-
|
"
|
|
97...122
|
-
|
a...z
|
123
|
-
|
{
|
|
124
|
-
|
??
|
125
|
-
|
}
|
|
126
|
-
|
~
|
128...159
|
-
|
A...Я
|
|
160...175
|
-
|
а...п
|
224...239
|
-
|
р...я
|
|
Управляющие клавиши и их сочетания со сдвиговыми
|
|
0
|
3
|
Ctrl-2
|
0
|
15
|
Shift - Tab
|
|
0
|
16...25
|
Alt-Q...Alt-P (верхний ряд букв)
|
0
|
30...38
|
Alt-A...Alt-L (средний ряд букв)
|
|
0
|
44...50
|
Alt-Z...Alt-M (нижний ряд букв)
|
0
|
59...68
72
|
F1...F10
курсор вверх
|
|
0
|
71
|
Home
|
0
|
75
|
курсор влево
|
|
0
|
73
|
PgUp
|
0
|
79
|
End
|
|
0
|
77
|
курсор вправо
|
0
|
81
|
PgDn
|
|
0
|
80
|
курсор вниз
|
0
|
83
|
Del
|
|
|
Страницы: 1, 2, 3, 4, 5, 6, 7, 8
|