1. Строка - это последовательность символов кодовой таблицы персонального компьютера. Количество символов в строке (длина строки) может динамически изменяться от 0 до 255. В Pascal строка трактуется как последовательность символов. Для строки из N символов отводится N+1 байт памяти: N байт – для хранения символов строки и один байт – для значения текущей длины строки. К любому символу в строке можно обратиться, указав его номер. В самом начале строки (под нулевым номером) расположен байт, содержащий значение текущей длины строки. Поэтому для определения объема памяти в байтах, требуемой для размещения строки, к значению ее максимальной длины прибавляется 1.
Рассмотрим структуру размещения строки в памяти на примере. Пусть М – максимальная длина строки, L – текущая длина, А – номер ячейки памяти, с которой начинается размещение строки, тогда:
А – содержит величину текущей длины (нулевой байт);
А+1 – содержит первый символ строки (1-ый байт);
А+L – содержит последний значащий символ (L-ый байт);
A+L+1
… – незанятые ячейки памяти, отведенные под строку.
A+M
2. Для определения строкового типа данных используется зарезервированное слово String, за которым следует заключенное в квадратные скобки значение максимально допустимой длины строки данного типа. Если это значение не указывается, то по умолчанию длина строки равна 255 байт. Переменную строкового типа в программе можно объявить двумя способами:
а) через раздел описания типов
Type <имя_типа_ строки> = String [<макс_длина_строки>];
Var <имя_переменной> :< имя_типа_строки>;
б) в разделе описания переменных.
Var <имя_строки>: String[<макс_длина_строки>];
Пример.Type Stroka= String [15];
Var B : Stroka;
Пример. Var B : String[15];
Определение строкового типа устанавливает максимальное количество символов, которое может содержать строка.
Строковые данные могут использоваться в программе также в качестве констант.
Пример.
Const
Address=’Березовая аллея, 25’;
При использовании в выражениях строка заключается в апострофы. Недопустимо применение строковых переменных в качестве селектора в операторе Case.
3. Для присваивания строковой переменной результата строкового выражения используется оператор присваивания.
Пример.
Var Str1, Fio : String[20];
…
Str1:=’Группа учащихся’;
Fio:=’Бочаров А. А.’;
Если значение переменной после выполнения оператора присваивания превышает по длине максимально допустимую при описании величину, все лишние символы справа отбрасываются.
Пример.
Описание А
Выражение
Значение А
A : String[6]A : String[8]A : String[2]
А:=’ГРУППА 1’;А:=’ГРУППА 1’;А:=’ГРУППА 1’;
’ГРУППА’’ГРУППА 1’’ГР’
Допускается смешение в одном выражении операндов строкового и символьного типов. Если при этом литерной переменной присваивается значение строкового типа, длина строки должна быть равной 1, иначе возникает ошибка.
4. К отдельным символам строки можно обратиться по индексу данного символа в строки, если рассматривать строку как массив символов. При этом нулевой элемент содержит код реальной длины строки, а элементы, начиная с 1-ого, - символы (отличие от обычных массивов). Индекс определяется выражением целого типа (а также целочисленной константой или переменной), которое записывается в квадратных скобках сразу за именем строковой переменной или константы.
Пример. Пусть Str:=’Алфавит’, тогда Str[1+2]=’ф’, Str[7]=’т’, Str[0]=chr(7) (в Str[0] записан код символа ‘ 7’).
Запись STR[0] дает доступ к нулевому байту, который предназначен для указания реально используемого количества символов строки и может изменяться от символа с кодом 0 (строка не содержит ни одного символа) до символа с кодом N (N – максимальный объявленный размер строки). Т. к. в строке не может быть более 255 символов, то максимальный код, хранящийся в нулевом байте равен chr(255).
5. Выражения, в которых операндами служат строковые данные, называются строковыми. Они состоят из строковых констант, переменных, указателей функций и знаков операций. Над строковыми данными допустимы: операция сцепления или конкатенации (+) и операции отношения (=, <>, >, <, >=, <=).
Операция сцепления применяется для сцепления (объединения) нескольких строк в одну результирующую строку (по принципу поезда).
Пример.
а) Str1:=’Группа учащихся’;
Str2:=’ школы – лицея’;
St:=Str1+ Str2; {St=’Группа учащихся школы - лицея’}
б) Str1:=’Группа учащихся’;
St:=Str1+ ’ школы – лицея’; {St=’Группа учащихся школы - лицея’}
в)
Выражение
Результат
‘А’+ ‘Т’+ ‘386’
‘Турбо ’+ ‘Паскаль ’+ ‘7.0’
‘АТ386’
‘Турбо Паскаль 7.0’
Следует помнить, что длина результирующей строки не должна превышать значения, указанного при ее описании в разделе Var, или 255 байтов (если не указана максимальная длина строки для этой переменной).
Операции отношения проводят сравнение двух строковых операндов и имеют приоритет более низкий, чем операция сцепления, т. е. сначала всегда выполняются все операции сцепления, если они присутствуют, и лишь потом реализуются операции отношения. Сравнение строк производится посимвольно слева направо до первого несовпадающего символа, и та строка считается больше, в которой первый несовпадающий символ имеет больший номер в стандартной таблице обмена информацией. Результат выполнения операций отношения над строковыми операндами всегда имеет логический тип и принимает значение True, если выражение истинно, и False, если ложно. Если строки имеют различную длину, но в общей части символы совпадают, считается, что более короткая строка меньше, чем более длинная. Строки считаются равными, если полностью совпадают по длине и содержат одни и те же символы.
Пример.
Выражение
Результат
‘MS-DOS’ < ‘MS-Dos’
True, т. к. коды заглавной буквы меньше кода строчной
‘program’ > ‘PROGRAM’
True, аналогично
‘Принтер ’ > ‘Принтер’
True, т. к. левый операнд длиннее на 1 символ (пробел в конце)
‘Intel’ = ‘Intel’
True, т. к. строки одной длины и содержат одни и те же символы
6. Для обработки строковых данных можно использовать стандартные процедуры и функции, описание которых можно найти в [1] или в любом справочнике по Pascal.
Задача
Проверить, является ли введенная совокупность символов именем месяца на английском языке (символы могут быть и строчными, и прописными).
Program Primer_String;Uses Crt, System;ConstNm : Array[1..12] of String[10]=(‘JANUARY’,‘JUNE’, ‘JULY’, ‘AUGUST’, ‘SEPTEMBER’,VarStr : String[10];i : Integer;Month : Boolean;BeginClrscr;Writeln(‘Введите символы (строку)’);Readln(Str);Month:=False;For i:=1 to Length(Str)Do Str[i]:=Upcase(Str[i]);For i:=1 to 12Do If Str = Nm[i]Then Month:=True;If MonthThen Writeln(‘Введено имя месяца’)Else Writeln(‘Введено не имя месяца’);Readkey;End.
{заголовок программы}{System – библиотека осн. функций Pascal}{раздел описания констант}‘FEBRUARY’, ‘MARCH’, ‘APRIL’, ‘MAY’,‘OСTOBER’, ‘NOVEMBER’, ‘DECEMBER’);{раздел описания переменных}{строка для ввода символов с клавиатуры}{параметр цикла For}{логическая переменная для записи рез-та}{начало программы}{очистка экрана}{ввод с клавиатуры посл-ти символов}{в строковую переменную Str}{}{преобразование всех символов строки Str}{в прописные буквы}{цикл проверки}{если Str – имя месяца}{то рез-т - истина}{если результат - истина}{то вывод «Введено имя месяца»}{иначе вывод «Введено не имя месяца»}{ожидание нажатия любой клавиши}{конец программы}
Файлы
1. Общие сведения.
Большие объемы (например, телефонный справочник) данных удобно записывать во внешнюю память в виде последовательности символов. Любой язык программирования должен иметь средства для организации хранения информации на внешних запоминающих устройствах и доступа к этой информации. В Pascal для этих целей предусмотрены специальные объекты – файлы. Файлом называется совокупность данных, записанная во внешней памяти под определенным именем. Целесообразность применения файлов продиктована следующими причинами:
- ввод больших объемов данных, подлежащих обработке, утомителен и требует большого времени; удобнее создать отдельный файл, который может быть подготовлен заранее и неоднократно использоваться;
- файл данных может быть подготовлен другой программой, становясь, таким образом, связующим звеном между двумя разными задачами, а также средством связи программы с внешней средой;
- программа, использующая данные из файла, не требует присутствия пользователя в момент фактического исполнения.
Файлы в языке Pascal подразделяются на текстовые файлы, файлы с объявленным типом данных (типизированные файлы), файлы с необъявленным типом данных (нетипизированные файлы). Рассмотрим теорию, относящуюся ко всем видам файлам, а на последующих двух занятиях более подробно будут рассмотрены текстовые и типизированные файлы.
2. Характеристики файла:
а) уникальное имя, что позволяет программе работать одновременно с несколькими файлами;
б) тип компонентов (любой тип данных языка Pascal, кроме файлового) – только для типизированных файлов;
в) длина вновь создаваемого файла никак не оговаривается при его объявлении и ограничивается только емкостью устройств внешней памяти.
3. Описание файлового типа.
Для доступа к файлу в программе должна быть описана специальная файловая переменная, которая считается представителем файлов в программе на Pascal:
Var
<имя_файловой_переменной> : <тип_файла>;
где <тип_файла> - определяется назначением файла, существует три возможных описания типа файлов:
а) для текстовых файлов
Var
<имя_файловой_переменной> :Text;
б) для типизированных файлов
Var
<имя_файловой_переменной> :File of <тип_компонентов>;
в) для нетипизированных файлов
Var
<имя_файловой_переменной> :File;
Пример.
Type Stroka=Srtring[15];
Var
F1 : File of Integer; {файловая перем. для типиз. файла с целочисленными компонентами}
F2 : File of Stroka; {файловая перем. для типиз. файла со строковыми компонентами}
F3 : Text; {файловая перем. для текстового файла}
F4 : File; {файловая перем. для нетипизированного файла}
4. Действия с файлами.
При использовании файлов в Pascal возможны три способа работы с ними:
- чтение файла с диска;
- запись файла на диск;
- редактирование файла.
Под чтением файла с диска понимается чтение (ввод) данных из файла на диске в оперативную память компьютера, в результате чего эти данные становятся доступными программе.
Под записью файла на диск понимается запись (вывод) данных из оперативной памяти компьютера на диск для хранения и дальнейшего использования этой же или другими программами.
Под редактированием файла понимается чтение файла, изменение считанных данных и запись измененных данных в файл.
5. Доступ к компонентам файла.
Файл представляет собой последовательность байтов, записанных на диске, которую пользователь интерпретирует нужным ему образом, например, как текст или последовательность чисел. Все компоненты файла считаются пронумерованными, начальный компонент имеет нулевой номер. Компонентом файла может быть число (целое или вещественное), символ, строка и т. д. В любой момент времени программе доступен только один компонент файла, на который ссылается текущий указатель (указатель обработки). Часто позицию размещения доступного компонента называют текущей позицией.
Все действия с файлами производятся покомпонентно, причем в этих действиях участвует тот компонент файла, на который указывает текущий указатель. В результате совершения операций чтения/записи указатель может перемещаться по компонентам файла.
По способу доступа к компонентам различают файлы последовательного и прямого доступа.
Файлом последовательного доступа называется файл, к компонентам которого обеспечивается доступ в том же порядке, в каком они записывались. Для поиска нужного компонента в таком файле необходимо, начиная с нулевого, перемещать указатель обработки до тех пор, пока он не будет указывать на искомый компонент. Т. е. необходимо последовательно при помощи указателя перебирать все компоненты файлы до требуемого компонента. При организации данных в файл последовательного доступа нельзя одновременно читать данные из файла и записывать данные в файл, т.к. для чтения компонента из последовательного файла указатель должен быть помещен на данный компонент, а для записи нового компонента в файл – в конец файла. Примером таких файлов являются текстовые файлы.
Файлом прямого доступа называется файл, доступ к компонентам которого осуществляется по адресу компонента. При поиске нужного компонента в таком файле достаточно указать номер его позиции. Примерами файлов прямого доступа могут быть типизированные и нетипизированные файлы.
6. Основные процедуры работы с файлами (на примере текстового файла).
Пример 1(написать на доске с комментариями и все процедуры объяснить на этом примере).
Program Primer;
Var F1, F2 : Text;
Name : String[30];
Begin
Assign(F1,’TTT.txt’); {установление соответствия между F1 и файлом в текущей папке}
{$I-}
Reset(F1);
{$I+} {открытие файла F1 на чтение}
If Ioresult <> 0
Then Writeln(‘Файл не найден’)
Else …(работа с файлом F1)
Name:=’C:\TP\WORK\Res.dat’; {задание абсолютного имени файла}
Assign(F2, Name); {установление соответствия между F2 и файлом Res.dat}
{$I-}
Rewrite(F);
{$I+} {открытие файла F1 на запись}
If Ioresult <> 0
Then Writeln(‘на диске нет места’)
Else … (работа с файлом F2)
Close(F1); {закрытие файла F1}
Close(F2); {закрытие файла F1}
Readln;
End.
а) Процедура Assign.
Каждому файлу в Pascal ставится в соответствие файловая переменная определенного типа для более полного использования возможностей операционной системы, поэтому перед началом работы с файлом необходимо установить данное соответствие. Для этого используется процедура Assign.
Назначение:
установление соответствия между файловой переменной и файлом на диске.
Синтаксис:
Assign ( F, Name ), где F – переменная любого файлового типа, Name – строка, содержащая полное имя файла в соответствии с требованиями операционной системы к именам файлов.
Описание работы:
процедура Assign устанавливает связь внешнего файла Name с файловой переменной F. Все последующие операции с файловой переменной F будут относиться к внешнему файлу с именем Name. Связь между файловой переменной F и файлом на диске Name существует до тех пор, пока с помощью процедуры Assign не будет установлено соответствие между файловой переменной F и другим внешним файлом.
Примечание:
- если указывается не абсолютное имя файла (только имя файла и его расширение), то этот файл программа будет искать только в текущем каталоге, т.е. там же, где расположена сама программа;
- для избежания ошибок лучше указывать абсолютное имя файла, начиная с имени диска.
б) Процедура Reset.
Чтению файла с диска должен предшествовать вызов процедуры открытия файла для чтения.
Назначение:
открытие существующего файла для чтения.
Синтаксис:
Reset (F), где F – файловая переменная.
Описание работы:
- процедура Reset, открывает уже существующий файл с именем, связанным с файловой переменной F;
- после открытия файла становится доступным только его начальный компонент;
- если файл уже открыт, процедура Reset вначале закрывает его, а потом снова открывает;
- если с помощью Reset, открывают несуществующий файл, то возникает ошибка.
Примечание:
- перед вызовом процедуры Reset должно быть установлено соответствие между файловой переменной F и файлом на диске;
- для предотвращения работы с несуществующим файлом используется функция статуса последней выполненной команды ввода/вывода – Ioresult (значение этой функции = 0, если открытие файла для чтения выполнено успешно, т. е. файл на диске существует и соответствие между ним и файловой переменной установлено правильно; значения этой функции ¹ 0 при попытке открыть для чтения несуществующий файл).
В примере 1 для правильной работы функции Ioresult директива {$I-} отключает контроль ошибок ввод/вывода, а директива {$I+} включает контроль ошибок ввода/вывода.
в) Процедура Rewrite.
Записи файла на диск должен предшествовать вызов процедуры открытия файла для записи.
Назначение:
открытие файла для записи.
Синтаксис:
Rewrite(F), где F – файловая переменная.
Описание работы:
- процедура Rewrite создает внешний файл на диске;
- если файл с таким именем уже существует, он стирается, и вместо него создается пустой файл;
- если файл с тем же именем уже открыт, он закрывается, стирается и создается заново;
- если с помощью процедуры Rewrite делается попытка открыть файл для записи при отсутствии на диске места для этого файла, то возникает ошибка.
Примечание:
- перед вызовом процедуры Rewrite имя внешнего файла должно быть задано предварительно и при помощи процедуры Assign должно быть установлено соответствие между файловой переменной F и именем файла;
- для обнаружения ошибки, связанной с отсутствием места на диске, следует использовать функцию Ioresult (значение этой функции = 0, если файл успешно открыт для записи, и ¹ 0, если файл открыть не удалось).
В примере 1 для правильной работы функции Ioresult директива {$I-} отключает контроль ошибок ввод/вывода, а директива {$I+} включает контроль ошибок ввода/вывода.
г) Процедура Close.
После завершения работы с файлом надо его закрыть, т. е. запретить доступ к файлу.
Назначение:
закрытие файла.
Синтаксис:
Close(F), где F – файловая переменная.
Описание работы:
процедура Close запрещает доступ к предварительно открытому файлу, т. е. делает его недоступным для чтения/записи.
Примечание:
- файл предварительно должен быть открыт для чтения или для записи.
Дополнительно (на усмотрение преподавателя!!!) процедуры Rename и Erase.
д) Процедура Rename.
Назначение:
переименование неоткрытого файла.
Синтаксис:
Rename(F, NewName), где F – файловая переменная, NewName – НОВОЕ имя файла.
- перед вызовом процедуры переименования файла должна быть установлена связь между внешним файлом со старым именем и файловой переменной;
- процедуру нельзя использовать для уже открытого файла, т. к. могут возникнуть нежелательные последствия со стороны операционной системы;
- переименование осуществляется только для реально существующих файлов, иначе возникает ошибка выполнения программы.
е) Процедура Erase.
Назначение:
удаление неоткрытого файла
Синтаксис:
Erase(F), где F – файловая переменная.
Описание работы:
процедура удаляет указанный файл с диска.
Примечание:
- перед вызовом процедуры удаления файла должна быть установлена связь между внешним файлом и файловой переменной;
- процедуру нельзя использовать для уже открытого файла, т. к. могут возникнуть нежелательные последствия со стороны операционной системы;
- удаление осуществляется только для реально существующих файлов, иначе возникает ошибка выполнения программы.
Пример 2. Удаление или переименование указанного файла.
Program Primer; {заголовок программы}
Uses Crt;
Var
F : Text; {F - файловая переменная}
Ch : Char; {Ch - символьная переменная}
St : String; {St - строковая переменная максимальной длины}
Begin
Clrscr;
Writeln(‘Введите имя файла’); {ввод с клавиатуры имени файла в переменную St}
Readln(St);
Assign(F, St); {установка соответствия между внешним файлом и переменной F }
Write(‘Удалить (У), Переименовать (П), Выход (В)’); {вывод меню}
Readln(Ch); {ввод пункта меню}
Case Ch of {начало оператора выбора}
‘У’, ‘у’ : Begin {если выбрано «Удалить», то происходит удаление файла}
Erase(F);
Writeln(‘Файл удален’); {вывод сообщения «Файл удален» на экран}
End;
‘П’, ‘п’ : Begin {если выбрано «Переименовать»}
Write(‘Введите новое имя файла: ’); {то ввод с клавиатуры}
Readln(St); {нового имени файла в строковую переменную St}
Rename(F,St); {переименование указанного файла}
Writeln(‘Файл переименован’); {вывод сообщения «Файл переименован»}
End;
‘В’, ‘в’ : Halt(1); {если выбран «Выход», то выход из программы}