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

Pascal Themes 5-10

.pdf
Скачиваний:
24
Добавлен:
15.04.2015
Размер:
452.27 Кб
Скачать

21

Тема 5. МАССИВЫ

1. Определение и атрибуты массива

Массив – это именованная упорядоченная совокупность однотипных данных, размещённых в основной памяти компьютера. Данные, образующие массив, называются его элементами. Элементы массива имеют общий идентификатор и различаются (идентифицируются) значениями величин, называемых индексами и определяющими месторасположение элемента в массиве.

Атрибутами, т.е. неотъемлемыми характеристиками массива являются: 1) имя, или идентификатор массива; 2) тип элементов; 3) размерность; 4) тип индексов.

Имя массива – это произвольный идентификатор.

Тип элементов массива может быть любым типом языка Турбо Паскаль.

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

Тип индексов в Турбо Паскале может быть любым порядковым типом, т.е. допустимы следующие типы индексов: 1) целый; 2) символьный; 3) логический; 4) перечисляемый; 5) отрезок целого; символьного, логического или перечисляемого типа. В подавляющем большинстве практических ситуаций тип индексов представляет собой отрезок целого типа.

2.Описание массива и обращения к его элементам

Синтаксическая форма описания массива имеет вид:

array[ t1 , t2 , , tk ] of telement

где array, of – зарезервированные слова; [], – синтаксические атрибуты; telement – тип элементов массива; t1 , t2 , , tk – типы индексов.

Указанное описание может использоваться в разделах описания констант, типов и переменных. Стилистической нормой является использование его разделе описания типов для создания имени нового типа, которое затем уже применяется в различных контекстах программы.

Пример описаний массивов:

22

const

nmax=10;{Максимальное число строк и столбцов матрицы, элементов вектора}

type

 

 

TElem=Real;

{ тип элементов вектора и матрицы

}

TIndex=1..nmax;

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

}

TVector=array[TIndex] of TElem; { тип – вектор элементов типа TElem,

}

 

{ с максимальным количеством элементов nmax }

TMatrix=array[TIndex, TIndex] of TElem; { тип – матрица элементов типа TElem}

var

{ размером nmax*nmax

}

 

 

V: TVector;

{ одномерный массив – вектор

}

A: TMatrix;

{ двухмерный массив – матрица

}

В данном примере определены четыре идентификатора типов:

TElem, TIndex, TVector и TMatrix. Первый из них TElem является синонимом

стандартного типа Real. Синонимы используются для того, чтобы при необходимости можно было быстро изменить тип в «нужных местах». Второй идентификатор TIndex именует тип индексов. Идентификаторы TVector и TVector – это имена типов массивов. Сами массивы V и A определяются в разделе var программы.

Замечания: 1) размерность массива определяется числом типов индексов, указанных в описании массива; 2) одномерные массивы используются для представления в программах математических объектов, называемых векторами; двухмерные массивы используются для представления математических объектов, называемых матрицами.

Обращение к элементу массива размерности k имеет вид

Name[e1 , e2 , , ek ] , где Name – имя массива, e1 ,e2 , ,ek – индексы, представляющие собой величины любого вида, т.е. могут быть константами, переменными, обращениями к функциям, элементами массивов и записей, выражениями соответствующих типов. Например, обращения к элементам массивов v и A из рассмотренного выше при-

мера могут иметь вид: V[2], V[i], V[25 mod nmax], A[i, j], A[5, j+3]. В этих при-

мерах предполагается, что переменные i и j имеют целый тип, причём значения i, j и j+3 не меньше 1 и не превышают nmax.

По режиму доступа элементы массива являются переменными.

Тема 6. ФАЙЛЫ

1.Объявление файлов

Файл представляет собой последовательность элементов одного

типа, расположенных на внешнем устройстве. Элементы могут быть любого типа, за исключением типа-файла и типа-объекта. Число элементов в файле не регламентируется, т.е. синтаксически не ограничи-

23

вается. Физическим ограничением является емкость магнитного носителя.

В Турбо Паскале имеется 3 категории файлов: текстовые, типизированные и файлы без типа.

1.Текстовый файл описывается ключевым словом Text и содержит символы, разделённые на текстовые строки с помощью управляющих символов CR (Carriage Return – возврат каретки, #13) и LF (Line Feed

перевод строки, #10). Эти символы размещаются в конце каждой строки. Эта особенность обеспечивает возможность вывода содержимого текстовых файлов на экран дисплея и на печать в виде обычного текста.

2.Типизированный файл описывается с помощью зарезервированных слов file и of, после чего указывается тип элементов файла.

3.Файл без типа описывается зарезервированным словом file без указания типа элементов. Ввод и вывод содержимого такого файла осуществляется блоками байтов фиксированной длины. При этом элементы файла могут иметь различный тип.

Пример.

type

 

 

 

TNumbers = file of Integer;

{ тип файла целых чисел

}

TSymbols

= file of 'A'..'Z';

{ тип файла прописных латинских букв

}

TUnTyp

= file;

{ тип файла элементов произвольного типа

}

Заметим, что тип Text не эквивалентен типу file of Char, они обрабатываются с помощью различных процедур и функций как разные типы данных.

Введя файловый тип, можно определить файловые переменные (переменные файлового типа):

var Fl, F2: TNumbers; F3: Text;

Тип файла можно задавать и непосредственно при объявлении файловых переменных:

var Fl, F2: file of Integer;

Файловые переменные имеют специфическое применение: их можно использовать лишь для выполнения операций с файлами (чтения, записи, удаления файла и т.д.) Над ними нельзя выполнять никаких иных операций (присваивать значение, сравнивать и т.д.)

2.Организация ввода-вывода

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

Перед тем, как осуществлять ввод-вывод, файловая переменная должна быть связана с конкретным файлом на диске с помощью процедуры Assign. Этим файлом может быть файл на магнитном диске или ленте, а также устройство вычислительного комплекса (клавиату-

24

ра, экран дисплея, принтер и т.д.). Затем файл должен быть открыт для чтения и/или записи. После этого можно осуществлять организацию ввода-вывода. Работа с различными категориями файлов отличается друг от друга.

Текстовые файлы являются файлами последовательного доступа. Типизированные файлы и файлы без типа – файлы с произвольным доступом (с помощью процедуры Seek можно установить указатель текущей позиции на произвольный элемент файла). Нумерация элементов файла начинается с нуля.

После работы с файлом он должен быть закрыт процедурой Close. Это требование особенно важно для текстового файла, в который производилась запись. Реальное взаимодействие программы с текстовым файлом осуществляется через буфер (участок основной памяти ЭВМ, длина которого по умолчанию составляет 128 байтов). После заполнения буфера его содержимое сбрасывается в файл. Процедура Close вызывает принудительный сброс содержимого незаполненного буфера в файл.

При работе с файлами могут возникать ошибки ввода-вывода. Эти ошибки могут проверяться либо операционной системой, либо программой пользователя.

С помощью директивы компилятора {$I+} включается системная проверка. В этом случае при возникновении ошибки выполнение программы завершается. Если же системная проверка ошибки отключена (с помощью ключа {$I–}), то при возникновении ошибки программа продолжает выполняться, и результат ввода-вывода можно проверить с помощью функции IOResult.

Заметим, что среда программирования Turbo Pascal имеет настройки, которые определяют директивы компилятора, действующие по умолчанию. Директивы компилятора, помещаемые в текст программы, имеют больший приоритет и отменяют настройки среды.

3.Стандартные процедуры и функции для всех типов файлов

Вданном разделе описаны процедуры и функции, предназначенные для выполнения операций ввода-вывода с файлами всех типов. Во всех этих процедурах и функциях F – файловая переменная, связанная с конкретным файлом процедурой Assign.

Процедуры

Assign (F, Name) – связь файловой переменной с внешним файлом. Связывает файловую переменную F с внешним файлом, имеющим имя Name. Name – переменная или константа типа string. Имя типа должно быть написано в соответствии с правилами MS DOS, может

25

включать путь и не должно превышать 79 символов. Если строка имени пустая, осуществляется связь со стандартным файлом ввода или вывода (см. п. 4).

Close (F) – закрытие открытого файла.

Закрывает внешний файл, с которым связана файловая переменная

F. При этом в случае необходимости в содержимое файла вносятся все произведенные изменения.

Reset(F[,Size]) – открытие существующего файла.

Открывается существующий файл, с которым связана файловая пе-

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

Необязательный параметр целого типа Size используется только с файлами без типа и задает размер пересылаемого блока данных в байтах. По умолчанию этот размер равен 128.

Rewrite (F[,Size]) – открытие нового файла для записи.

Открывается новый пустой файл, и ему присваивается имя, заданное процедурой Assign. Если файл с таким именем уже существует, то он уничтожается. Необязательный параметр Size имеет тот же смысл, что и в процедуре Reset.

Функции

Eof(F) – возвращение признака конца файла.

Принимает значение True, если указатель текущей позиции файла

находится за последним элементом файла (за последним символом, если файл текстовый), и False – в противном случае.

IOResult – результат последней операции ввода-вывода. Возвращает число 0, если операция ввода-вывода завершилась ус-

пешно, и другое число – в противном случае.

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

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

Имеется две стандартные файловые переменные для текстового файла: Input и Output Переменная Input по умолчанию связана с клавиатурой, а Output – с экраном дисплея.

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

Assign(Input,''); Reset(Input); Assign(Output,''); Rewrite(Output);

26

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

не указана файловая переменная, то фактически используются файловые переменные Input или Output.

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

Ниже описаны основные процедуры и функции, предназначенные для выполнения операций ввода-вывода с текстовыми файлами. Как и ранее, F – файловая переменная, связанная с конкретным файлом процедурой Assign.

Процедуры

Append(F) – открытие файла для добавления данных в конец файла. Открывается существующий файл, с которым связана файловая пе-

ременная F, и указатель текущей позиции файла устанавливается в конец файла, т.е. за его последний элемент.

Flush(F) – освобождение буфера выходного файла.

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

файловая переменная F.

Read(F, <список ввода>) – ввод (чтение) данных из файла.

Из файла, с которым связана файловая переменная F, извлекаются значения, которые присваиваются переменных списка ввода (см. п. 5).

Readln(F, <список ввода>) – то же, что и процедура Read, но после чтения значения последней переменной списка ввода указатель текущей позиции файла перемещается в начало следующей строки, т.е. указатель «перескакивает» через символы признака конца строки CR и LF.

SetTextBuf(F, Buf [, Size]) – назначение буфера ввода-вывода.

Для файла, с которым связана файловая переменная F, назначается

буфер ввода-вывода в виде переменной Buf (любого типа). Необязательный параметр Size задает размер буфера в байтах. Если этот параметр не указан, в качестве буфера используется вся переменная Buf. Если эта процедура не применяется, для организации ввода-вывода по умолчанию назначается стандартный буфер ввода-вывода размером в 128 байтов.

Write(F, <список вывода>) – вывод (запись) данных в файл.

Вфайл, с которым связана файловая переменная F, записываются значения выражений списка вывода (см. п. 5).

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

27

Функции

Eoln(F) – – возвращение признака конца строки файла.

Принимает значение True, если текущим элементом файла является

признак конца строки или если функция Eof(F) принимает значение True. В остальных случаях функция принимает значение False.

SeekEof (F) – возвращение признака конца файла.

Отличается от Eof(F) тем, что стоящие в конце файла пробелы,

символы табуляции и признака конца строки (CR, LF) пропускаются.

SeekEoln(F) – возвращение признака конца строки файла. Отличается от Eoln(F) тем, что стоящие в конце строки символы

пробела и табуляции пропускаются.

Пример. Прочитать из текстового файла А все записанные в него целые числа, преобразовать их в вещественные и вывести в текстовый файл В по 4 числа в строку.

program Example; var

F1, F2: Text; X: Real;

i: Integer; begin

{$I-} { включение программной проверки правильности файловых операции }

Assign(F1, 'А.txt');

{ связь с файлом А, содержащим целые числа

}

Reset(F1);

{ открытие файла для чтения

 

}

{$I+}

{ включение системной проверки

}

if IOResult <>0

 

 

 

 

then Writeln('Heт файла А')

 

 

else begin

 

 

 

 

Assign(F2, 'В.txt'); {связь с файлом В

}

 

Rewrite(F2);

{открытие файла для записи

}

 

repeat

 

 

 

 

for i := 1 to 4 do

 

 

 

if not SeekEof(F1l)

 

 

 

then begin

 

 

 

 

Read(F1, X);

 

 

 

Write(F2, X:18);

{ форматированный вывод - см. ниже

}

end;

 

 

 

 

Writeln(F2)

 

{ переход на новую строку

}

until SeekEof(F1); Close(F1); Close(F2);

end; end.

5.Ввод данных из текстового файла

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

Read и Readln, их назначение описано в п. 4. Синтаксическая форма использования этих процедур следующая:

Read(F, <список ввода>); Readln(F, <список ввода>);

28

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

Переменные списка ввода могут иметь следующие типы: целые, вещественные, Char, string и одномерный массив символов с нулевой нижней границей индекса – array[0..N] of Char, где N – целая констан-

та (N 65534).

В текстовом файле данные хранятся в виде символов. Во время ввода происходит автоматическое перекодирование информации в двоичный формат.

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

Ввод значений переменных различного типа отличается алгоритмом выявления соответствующих констант.

При вводе числовых данных (целого и вещественного типов) пробелы, символы табуляции и признаки конца строки (символы CR и LF) воспринимаются как разделители. Все они пропускаются в процессе поиска последовательности символов, которая может быть воспринята как константа соответствующего типа.

При вводе символа из текущей позиции файла читается один символ, в том числе и символ возврата каретки CR (арифметический код 13), если функция Eoln(F) дает значение True. Никаких разделителей для данных символьного типа нет.

При вводе переменной s типа string символы CR и LF являются разделителями и не заносятся в переменную. В процессе ввода из файла извлекаются символы и помещаются в переменную s до тех пор, пока не произойдёт одно из двух событий: либо переменная оказывается полностью заполненной, либо достигнут конец текстовой строки в файле, т.е. встречен символ CR. В первом случае динамическая длина значения переменной Length(s) оказывается максимально возможной и равной уменьшенному на единицу количеству байтов, выделенных под переменную, т.е. Length(s) = SizeOf(s) – 1. Во втором случае

Length(s) < SizeOf(s) – 1.

29

Ввод одномерного массива символов с нулевой нижней границей индекса – array[0..N] of Char – полностью аналогичен вводу переменных типа string, отличие состоит только в том, что после завершения формирования значения массива в байт за последним символом помещается ноль.

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

Приведённые правила ввода значений переменных и различие между процедурами Read и Readln определяют форму записи констант в файле исходных данных. Попробуйте сформулировать их самостоятельно.

6.Вывод данных в текстовый файл

Вывод информации в текстовый файл (в том числе и на экран дис-

плея) осуществляется с помощью процедур Write и Writeln, их назначение описано в п. 4. Синтаксическая форма использования этих процедур следующая:

Write(F, <список вывода)); Writeln(F, <список вывода>);

Число элементов списка вывода может быть любым (в том числе и нулевым; при этом процедура Write не выполняет никаких действий, а процедура Writeln осуществляет переход на новую строку).

Переменные списка вывода могут иметь следующие типы: целые, вещественные, Char, Boolean, string, PChar и одномерный массив символов с нулевой нижней границей индекса.

В памяти ЭВМ значения величин хранятся в двоичном коде. Во время вывода происходит их автоматическая перекодировка в символьную форму.

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

Writeln('Площадь фигуры равна: ', SFig); Writeln('Строка ', Name, ' содержит ', Len, ' символов');

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

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

Вывод данных вещественных типов по умолчанию осуществляется

30

в виде мантиссы с порядком. Количество знакомест, выделяемых под число, зависит от установок опций компилятора в секции Numeric processing или соответствующих явных директив {$N} и {$E}. Обычно эти установки соответствуют директивам {$N+} и {$E+}, поскольку при этом допустимо использование всех вещественных типов, а не только одного типа Real, и не надо задумываться о наличии арифметического сопроцессора (хотя практически во всех современных ЭВМ он имеется). В указанном случае для каждого вещественного значения по умолчанию выводятся: 1) знак числа (вместо знака «+» выводится пробел); 2) старшая значащая цифра числа; 3) десятичная точка; 4) остальные четырнадцать десятичных цифр мантиссы; 5) буква E; 6) знак порядка; 7) четырехзначный порядок числа. Таким образом, всего отводится 23 позиции, например, число –175,18 выводится в следующем виде:

–1.75179999999935E+0002

Отличие от ожидаемого значения –1.75180000000000E+0002 объясняется ошибкой округления (многие дробные числа в памяти ЭВМ представляются неточно, ошибка округления имеет порядок 10L, где L – количество значащих десятичных цифр, поддерживаемых в конкретном вещественном типе; например, для типа Real L = 11).

При выводе символа отводится одна позиция. При выводе строки – число позиций, равное длине строки.

В случае логической величины выводится ее значение словами

TRUE или FALSE.

Изложенное выше необходимо учитывать при последовательном выводе нескольких данных (например, нескольких чисел, символов, string-строк, логических величин). Чтобы отдельные значения не сливались друг с другом, следует предусматривать вывод разделяющих пробелов и разнесение информации по разным текстовым строкам.

7.Форматированный вывод в текстовый файл

Изменить стандартную форму вывода можно используя форматы

языка Паскаль. Всего в языке существует два формата вывода, которые записываются через двоеточие после соответствующего элемента вывода, например:

Write(Expression: М: N);

В этом примере Expression – выражение, значение которого выводится в файл (в данном случае – на экран дисплея); М и N – форматы, которые синтаксически представляют собой выражения целого типа.

Первый формат можно использовать при выводе значений любого типа, – он определяет размер поля, в которое выводится данное значение. Выводимая информация выравнивается по правому краю поля,

31

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

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

Пример. Вывести на экран дисплея таблицу умножения целых чисел от 1 до 9.

program Example;

 

 

 

 

 

 

 

 

var i, j: Byte;

 

 

 

 

 

 

 

 

 

 

begin

 

 

 

 

 

 

 

 

 

 

Writeln;

 

 

 

 

 

 

 

 

 

 

Writeln('ТАБЛИЦА УМНОЖЕНИЯ': 45);

 

 

 

 

 

Write(' ':10);

 

 

 

 

 

 

 

 

 

 

for j := 1 to 9 do Write(j: 6);

 

 

 

 

 

 

 

Writeln; Writeln(' ':10,‘----------------------------------------------------------------------

 

 

 

 

 

 

 

‘);

for i := 1 to 9 do begin

 

 

 

 

 

 

 

 

Write(i:6, 'I': 4);

 

 

 

 

 

 

 

 

for j := 1 to 9 do Write(i * j: 6);

 

 

 

 

 

 

Writeln;

 

 

 

 

 

 

 

 

 

 

end;

 

 

 

 

 

 

 

 

 

 

end.

 

 

 

 

 

 

 

 

 

 

 

 

1

2

ТАБЛИЦА УМНОЖЕНИЯ

6

7

8

9

 

 

3

4

5

1

------------------------------------------------------------------------------------------

I 1

2

3

4

5

6

7

8

9

2

I

2

4

6

8

10

12

14

16

18

3

I

3

6

9

12

15

18

21

24

27

4

I

4

8

12

16

20

24

28

32

36

5

I

5

10

15

20

25

30

35

40

45

6

I

6

12

18

24

30

36

42

48

54

7

I

7

14

21

28

35

42

49

56

63

8

I

8

16

24

32

40

48

56

64

72

9

I

9

18

27

36

45

54

63

72

81

8.Стандартные процедуры и функции для типизированных файлов

При работе с типизированными файлами используются следующие

дополнительные процедуры и функции (здесь также F – файловая переменная, связанная с конкретным физическим файлом процедурой

Assign).

32

Процедуры

Read(F, <список ввода>) – чтение данных из файла.

То же, что и процедура Read для текстовых файлов, но переменные,

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

Seek(F, Num) – установка указателя текущей позиции файла на требуемую компоненту.

Указатель устанавливается на компоненту файла с номером Num. Нумерация компонент начинается с нуля.

Truncate (F) – удаление части файла, начиная с текущей позиции. Удаляется часть файла, начиная с текущей позиции и до его конца.

Write(F, <список вывода>) – запись данных в файл.

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

Функции

FilePos(F) – номер текущей компоненты файла.

Функция возвращает номер текущей компоненты файла. Нумера-

ция компонент начинается с нуля.

FileSize(F) – текущий размер файла.

Функция возвращает текущий размер файла, представляющее со-

бой количество компонентов этого файла.

Пример. Из текстового файла Float.txt прочитать попарно вещественные числа и, считая в каждой паре первое число действительной, а второе – мнимой составляющей, записать их в файл комплекс-

ных чисел Сomplex.rec.

program Example; type

TComplex = record

Re, Im: Real; end;

var

Fl: Text;

F2: file of TComplex; X: TComplex;

begin

{$I-}

Assign(F1, 'Float.txt'); Reset(F1); {$I+}

if IOResult <> 0

33

then Writeln('Heт исходного файла') else begin

Assign(F2, 'Complex.rec'); Rewrite(F2); while not SeekEof(F1) do begin

Read(F1, X.Re); if SeekEof(F1) then X.Im:=0

else Read(F1, X.Im); Write(F2, X);

end;

Close(F1); Close(F2) end;

end.

Контрольные вопросы

1.Что представляет собой файл? Какие типы файлов вы знаете?

2.Какой файл определяет стандартный тип Text?

3.Для чего используются файловые переменные?

4.Как выполняется связь файловой переменной с внешним файлом?

5.Каким образом можно организовать ввод-вывод из файла?

6.Каким образом используются функции Eof и Eoln при чтении информации из файла?

7.Как можно проверить и обработать ошибки ввода-вывода?

8.Каковы особенности выполнения процедур Read и Write при работе с текстовыми файлами?

9.Как можно использовать стандартные файловые переменные

Input и Output?

10.Как можно дописать информацию в конец текстового файла?

11.Для чего нужно выполнять вызов процедуры Close или Flush для файла, в который выводилась информация?

12.Какие действия выполняются при вводе числовых данных из текстового файла?

13.Как вводятся символы из текстового файла?

14.Как вводятся строки из текстового файла?

15.Как выполняется форматированный вывод в текстовый файл?

16.Как устанавливается указатель текущей позиции на требуемый элемент типизированного файла?

17.Как определить номер текущего элемента типизированного фай-

ла?

18.Как удалить часть типизированного файла, начиная с текущего элемента?

19.Как определить номер текущей компоненты типизированного файла?

20.Как определить текущий размер типизированного файла?

34

Тема 7. СТРОКИ

1. Строковые константы

Строковая константа – это последовательность любого количества символов из набора ASCII, расположенных на одной строке и заключенных в апострофы. Прямые ограничения на длину строковой константы отсутствуют, но имеется одно косвенное ограничение компилятора Турбо Паскаля: длина любой строки программы не может превышать 126 символов.

Строка из одного символа называется символьной константой. Если между апострофами нет ни одного символа, то такая строка

называется нулевой или пустой строкой.

Если в строку необходимо поместить символ «апостроф», его следует записать дважды, например, 'Еженедельник ''PC WEEK'''.

Существует три альтернативных способа представления символов в программе:

запись изображения символа в апострофах;

комбинация символа # с целой беззнаковой константой из диапазона 0..255, эта константа представляет собой ASCII-код символа;

комбинация символа ^ с заглавной латинской буквой A .. Z или одного из следующих символов: [ \ ] ^ _ .

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

Второй – для представления всех символов таблицы ASCII.

Третий – для представления управляющих символов с кодами 1..31 (код символа, записываемого после символа ^, равен коду нужного управляющего символа плюс 64).

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

Пример. Строковые константы.

const

 

 

 

Blanks = '

';

{ 10 пробелов

}

January = 'Январь';

{ 6 символов – русских букв

}

Apostrophe = '''';

{ один символ – апостроф

}

Bell = 'Bomm!'#7;

{ 6-й символ строки – символ с кодом 7

}

{ Строка, содержащая символы с кодами 13 (CR) и 10 (LF)

}

TwoLines = 'Строка1'#13#10'Строка2';

 

Return = ^M^J;

 

{ управляющие символы с кодами 13 и 10

}

35

2.Строка типа string

ВТурбо Паскале тип строка – стандартный тип string – определяет последовательность символов произвольной длины (максимальная длина строки – 255 символов). У типа строки в квадратных скобках может быть указана максимальная длина значения от 1 до 255 (в этом случае тип является нестандартным). Если размер строки не указан, он считается равным 255, например:

var

 

Line: string[80];

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

MaxStr: string;

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

Структурно строка N символов эквивалентна массиву из N+1 символа со следующим описанием:

string[N] = array[0..N] of Char

К элементам строки можно обращаться как к элементам массива, например, Line[1] – это первый символ строки Line.

Под переменную-строку выделяется N + 1 байт памяти, где N – константа, указанная в описании строки. Размер переменной-строки (количество байтов, отведённых под переменную), как и переменной любого другого типа, может быть получен с помощью стандартной функции SizeOf(s). Очевидно, что для строк имеет место равенство

SizeOf(s)=N+1.

Нулевой символ (байт) предназначен для хранения длины текущего значения строки (числа символов, занесенных в строку). Его арифметическое значение может изменяться от 0 до N. Однако следует помнить, что нулевой байт, как и все остальные байты строки имеют тип Char, т.е. интерпретируется как символ. С ним можно работать, как и с остальными символами строки (записывать и читать его значение)

NB

Формирование нулевого байта строки выполняется автома-

 

тически, если строка получает значение с помощью оператора присваивания или при чтении ее значения с внешнего устройства.

Прямое изменение значения нулевого байта приводит к изменению длины текущего значения строки! При этом необходимо помнить, что перед записью текущий размер строки необходимо преобразовать к символьному типу с помощью функции Chr. Если необходимо использовать нулевой байт строки в программе, то с помощью функции Ord выполняется его преобразование к целому типу.

Пример. Искусственное формирование строки букв от 'A' до 'Z'.

var Letters : string;

 

i: Byte; с: Char;

 

begin

 

i := 0;

{ начальное значении счётчика символов строки }

36

for c := 'A' to 'Z' do begin { движение по таблице кодов ASCII от A до Z

}

Inc(i);

{ номер очередного символа строки

}

Letters[ i ] := c;

{ запись символа в строку

}

end; {for c}

 

 

Letters[0] := Chr(i);

{ запись размера полученной строки в нулевой байт }

end.

NB

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

Например, формирование строки Letters из последнего примера целесообразнее выполнить с использованием операции сцепления строк:

Letters := '';

for с := 'A' to 'Z' do Letters := Letters + c;

Нулевой байт с текущей длиной строки при этом формируется автоматически.

3.Типизированные строковые константы

Начальное значение типизированной константы строкового типа

может быть строковой константой любой допустимой длины. Если длина значения константы превышает объявленный размер строки, то лишние символы начального значения отбрасываются, например:

const

 

 

Name : string[8] = 'Сергей';

{ Name = 'Сергей', текущая длина 6

}

Digits : string[8] = '1234567890';

{ Digits = '12345678', текущая длина 8

}

4. Присваивание значения строковой переменной

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

const Point: Char = '.';

{ константа символьного типа }

var

 

 

 

 

s1: string[10];

 

 

 

s2, s3: string[5];

 

 

 

begin

 

 

 

s1

:= 'Microsoft_Word_97';

{ s1

= 'Microsoft_'

}

s2

:= s1;

{ s2

= 'Micro'

}

s3

:= Point;

{ s3

= '.'

}

end.

 

 

 

 

37

5.Ввод – вывод строк

Ввод строки осуществляется процедурой Readln с соответствую-

щей строковой переменной в списке ввода. Введенное значение строки определяется размером строки и количеством символов в строке ввода (до нажатия на клавишу «Enter»). Если число символов в строке ввода больше объявленного размера (N) строки, то в строку записываются первые N символов. Если число символов в строке ввода меньше размера строки, то в строку переписываются все символы из строки ввода, количество этих символов определяет длину значения строки. Формирование нулевого байта строки во время ввода выполняется автоматически.

Пример. Ввод строки

var

s: string[5]; begin

Readln(s);

Строка ввода

 

s

Значение

Длина значения

 

Microsoft_Word_97

'Micro'

5

Turbo_Pascal

'Turbo'

5

1234567

'12345'

5

Bell

'Bell'

4

 

''

0

При вводе нескольких строк одной процедурой ввода следует иметь в виду, что разделитель для строковых значений отсутствует, и символы из строки ввода последовательно заносятся во вводимые строки до тех пор, пока не будет нажата клавиша «Enter».

Пример. Ввод нескольких строк одной процедурой ввода.

var

s1, s2, s3: string[5]; begin

Readln(s1, s2, s3);

Строка ввода

s1

 

s2

 

s3

 

Значение

Длина

Значение

Длина

Значение

Длина

Microsoft_Word_9

'Micro'

 

5

'soft_'

5

'Word_'

5

7

 

 

 

 

 

 

 

Turbo_Pascal

'Turbo'

 

5

'_Pasc'

5

'al'

2

1234567

'12345'

 

5

'67'

2

''

0

Bell

'Bell'

 

4

''

0

''

0

 

''

 

0

''

0

''

0

Для вывода строки соответствующая строковая переменная помещается в список вывода процедуры Write или Writeln. Количество выводимых символов равно длине значения строки.

38

При выводе строки можно использовать форматирование – указывать ширину поля, в котором выводится значение строки. Если ширина поля меньше длины значения строки, то выводится вся строка, а указанное в формате число позиций игнорируется. Если ширина поля больше длины значения строки, то выводимая строка выравнивается по правой границе поля.

Пример. Вывод строки s='Слово'

Список вывода

Выводимая строка

s

Слово

s:3

Слово

s:5

Слово

s:8

Слово

Чтобы вывести строку s в поле длиной m с выравниванием по левой границе поля, необходимо вывести строку, а затем m-Length(s) пробелов, т.е. использовать следующий оператор:

Writeln(s, ' ':m-Length(s));. { для пробела отводится поле длиною m-Length(s) }

6.Строковые операции

Для строк применимы операции конкатенации (+) и отношения (<,

<=, >, >=, =, <>).

Операция конкатенации (сцепления) добавляет к первой строке вторую. Также можно объединять строку и символ.

Пример. Объединение двух строк.

const

Blank: Char = ' ';

{ символ пробела

}

var s1, s2, s3: string[80];

 

 

 

begin

 

 

 

 

s1

:= 'Turbo'; s2 := 'Pascal';

 

 

s3

:= s1 + Blank + s2;

{ s3

= 'Turbo Pascal'

}

Если в результате конкатенации получается строка длиной более 255 символов, то она усекается до 255 символов.

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

Например:

'A' < 'B'

{ Ord('A')=65, Ord('B')=66

}

'Alph' < 'Alpha'

{ пустой символ меньше любого другого символа

}

'Alpha' < 'B',

{ 'A' < 'B'

}

'Betta' < 'betta'

{ 'B' < 'b'

}

'Петров' > 'Иванов'

{ 'П' > 'И'

}

'стол' < 'стон'

{ 'л' < 'н'

}

't'#7 >'t'

{ символ #7 больше пустого символа

}

Здесь для наглядности приведены только строковые константы, хотя можно сравнивать любые строковые и символьные выражения.

39

7. Строковые процедуры

procedure Delete(var s: string; Index: Integer; Count: Integer);

Удаляет подстроку из строки s.

s – исходная строка;

Index – номер первого удаляемого символа; если номер больше длины строки, то символы не удаляются и строка s не изменяется;

Count – число удаляемых символов; если значение Index+Count больше длины строки s, то будет удален конец строки s, начиная с позиции Index.

Например:

s := 'Подстрока'; Delete(s, 1, 3);

{ s = 'строка'

}

s := 'Максимум'; Delete(s, 6, 2);

{ s = 'Максим'

}

s := 'Минимум'; Delete(s, 5, 10);

{ s = 'Мини'

}

procedure Insert(Source: string; var s: string; Index: Integer);

Помещает подстроку Source в строку s, начиная с позиции Index;

если получается строка длиннее, чем максимальная (объявленная) длина s, то она усекается до максимальной длины s.

s – исходная строка;

Source – подстрока, помещаемая в строку;

Index – номер позиции исходной строки, начиная с которой размещается подстрока; если Index больше длины s, то результатом будет s+Source (сцепление двух строк).

Например:

s := 'Форма'; Insert('ул', s, 5);

{ s = 'Формула'

}

s := 'Форма'; Insert('ция', s, 20);

{ s = 'Формация'

}

procedure Str(e[:M[:N]]; var s: <строковый тип>);

Преобразует число в последовательность символов. e – выражение целого или вещественного типа;

s – строка типа string или PСhar, в которую записывается символь-

ное представление числа;

M, N – форматы вывода целого типа (по аналогии с процедурой

Write).

Например:

I:=1234;

Str(I, s);

{ s = '1234'

}

I:=1234;

Str(I:5, s);

{ s = '

1234'

}

X:= 2.5e4;

Str(X, s);

{ s = '

2.50000000000000Е+0004'

}

X:= 2.5e4;

Str(X:9:2, s);

{ s = '

25000.00'

}

procedure Val(s: <строковый тип>; var V; var Code: Integer);

Преобразует символьное представление числа в двоичную форму.

s – строка типа string или PChar с символьным представлением

числа;

V – переменная целого или вещественного типа для записи двоичного представления числа;

Code – номер неправильного символа, если символьное представ-

40

ление числа недопустимо для типа V (значение V при этом становится равным нулю); Code = 0, если изображение числа правильное.

В строке s ведущие пробелы допустимы. Завершающие пробелы в строке интерпретируются как ошибочные символы и должны быть удалены перед использованием процедуры Val.

Например:

s := '234'; Val(s, I, Res);

{ I = 234;

Res = 0

}

s := '12x'; Val(s, I, Res);

{ I = 0;

Res = 3

}

s := '12 '; Val(s, I, Res);

{ I = 0;

Res = 3

}

s := '2.5e4'; Val(s, X, Res);

{ X = 25000.0; Res = 0 }

8. Строковые функции

function Concat(s1[, s2, …, sn]: string): string;

Объединяет несколько строк в одну и усекает, если необходимо,

результирующую строку до 255 символов. s1, s2, …, sn – объединяемые строки.

Эта функция полностью эквивалентна операции «+» и включена в Турбо Паскаль для совместимости с другими компиляторами.

s1 := 'Turbo'; s2 := 'is fastest';

s := Concat(s1, ' Pascal ', s2); { s = 'Turbo Pascal is fastest'}

function Copy(s: string; Index: Integer; Count: Integer): string;

Возвращает подстроку строки s. s – исходная строка;

Index – номер первого копируемого в подстроку символа строки

(если Index больше размера строки, то возвращает пустую строку); Count – число копируемых в подстроку символов (если Index +

Count больше размера s, то возвращается имеющийся остаток строки).

s := 'Алгоритм';

 

 

 

s1 := Copy(s, 3, 5);

{ s1

= 'горит'

}

s2 := Copy(s, 10, 2);

{ s2

= '' – пустая строка

}

s3 := Copy(s, 5, 10);

{ s3

= 'ритм'

}

function Length(s: string): Integer;

Возвращает длину текущего значения строки.

s – строка, у которой определяется длина значения.

s := '123456789';

n := Length(s); { n = 9 }

function Pos(Substr, s: string): Byte;

Возвращает позицию, с которой подстрока Substr первый раз вхо-

дит в строку s. Предполагается, что позиция первого символа строки равна 1. Если подстрока Substr в строке s не найдена, то функция Pos возвращает значение 0.

s := 'Программа';

 

n := Pos('рог', s);

{ n = 2 }

n := Pos('гор', s);

{ n = 0 }

n := Pos('П', s);

{ n = 1 }

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