1.7.2.2 Строковый тип
Строковые типы используются для определения произвольных наборов символов. Строку можно определить как одномерный массив с переменными границами, каждый элемент которого является символом типа Char.
Строковый_тип::= Стандартный_строковый_тип |
ASCIIZ_тип
Изначально в Паскале, а затем и в ТП существовал только один строковый тип, максимальная длина которого не могла превышать 255 байт. Одной из особенностей данного типа было то, что первый байт строки означал ее актуальную длину (отсюда и ограничение на 255 символов). При этом во многих других языках, и прежде всего в языке Си для организации строк используется совершенно другая структура, основанная на последовательности символов, заканчивающейся нулем. Длина такой последовательности может быть до 64 килобайт, что вполне достаточно для хранения небольших текстов. Поэтому для совместимости с другими языками в седьмую версию ТП был введен ASCIIZ тип (ASCII - американский стандарт набора символов, Z (zero-нуль) - заканчивающегося нулем).
Справедливости ради следует сказать, что несмотря на широкое распространение в программировании ASCIIZ строк, манипулировать стандартными паскалевскими строками значительно проще и надежнее. По видимому для этого фирма Inprise (ранее - Borland International inc.) ввела в Delphi понятие длинной строки (WideString), которая совмещает в себе все достоинства стандартных и ASCIIZ строк и простейшим преобразованием типов (а для стандартных строк даже и этого не требуется) может быть приведена к любому из них.
Стандартный строковый тип
Стандартный_строковый_тип ::=
"string" [ "[" "целое_без_знака" "]"]
Число в скобках означает максимальную длину строки. Если оно отсутствует, то максимальная длина строки =255 символам. Объем памяти, занимаемый строкой, равен ее максимальной длине, вне зависимости от актуальной длины, значение которой находится в промежутке от 0 до максимальной длины.
Аналогично элементу массива можно проиндексировать строковую переменную, причем значение индекса должно принадлежать промежутку от 0 до максимального размера строки. Таким образом можно получить доступ к каждому символу строки типа Char. Нулевой символ строки представляет собой после перевода в целочисленное выражение актуальную длину строки.
Задача 29. Ввести с клавиатуры строку и вывести ее задом наперед.
var s:string;
i:byte;
begin
readln(s);
for i:=ord(s[0]) downto 1 do write(s[i]); {открываем цикл от актуальной длины строки до 1. В теле цикла выводим все символы строки}
writeln;
readln;
end.
Для стандартных строк можно использовать операции отношения. При сравнении строк сравниваются последовательно все символы с одинаковыми индексами в соответствии с таблицей ASCII. Операция сравнения завершает свою работу, как только значение символа одной строки станет больше, чем значение символа с таким же порядковым номером из другой строки. Если одна строка длиннее другой, то она считается большей в операциях сравнения, только если ее начало равно более короткой строке.
Например:
Процедура writeln('AA'>'BB') выведет на экран FALSE;
Процедура writeln('AA'='aa') выведет на экран FALSE;
Процедура writeln('Привет'<'Привет, друг!') выведет на экран TRUE;
Модуль System содержит большой набор функций и процедур, предназначенных для работы со стандартными строками.
Function Concat(s1 [, s2,..., sn]: String): String; |
Функция Concat объединяет переданные ей строки, присоединяя каждую последующую к концу предыдущей и возвращает полученный результат. Функция эквивалентна строковой операции контактенции "+" |
Function Copy(S: String; Index: Integer; Count: Integer): String; |
Функция Copy возвращает вырезку из строки S, начиная с символа, номером которого Index в количестве Count символов |
Procedure Delete(var S: String; Index: Integer; Count:Integer); |
Процедура Delete удаляет из строки S подстроку, начиная с символа, номер которого Index в количестве Count символов. |
Procedure Insert(Source: String; var S: String; Index: Integer); |
Процедура Insert вставляет строку Source в строку S, начиная с позиции Index строки S. |
Function Length(S: String): Integer; |
Функция Length возвращает длину переданной ей строки (эквивалентно ord(s[0])) |
Function Pos(Substr: String; S: String): Byte; |
Функция Pos возвращает номер позиции первого вхождения подстроки Substr в строку S. Если подстрока Substr в строке S отсутствует, то функция возвращает 0. |
procedure Str(X [: Width [: Decimals ]]; var S:string); |
Процедура Str переводит число X в строку S с возможностью форматирования (также как для форматированного вывода с помощью процедур Write и Writeln) |
Procedure Val(S:string; var V; var Code: Integer); |
Процедура Val переводит строку S в число V. Если перевод невозможен (например из-за недопустимых символов в строке, или из-за несоответствия типов - попытка перевода строкового представления вещественного числа в целочисленную переменную V), то в переменной Code возвращается код ошибки. Если перевод прошел нормально, в переменной Code возвращается 0. |
Задача 30. Ввести с клавиатуры и объединить три строки.
var s1,s2,s3,s:string;
begin
readln(s1);
readln(s2);
readln(s3);
s:=concat(s1,s2,s3); {объединяем введенные строки с использованием функции concat}
writeln(s);
s:=s1+s2+s3; {объединяем введенные строки с использованием операции контактенции }
writeln(s);
readln;
end.
С помощью данной программы можно сравнить результаты действия функции Concat и операции контактенции.
Задача 31. Заменить в строке все знаки присваивания (':=') на знаки равенства ('=').
При решении данной задачи воспользуемся небольшой хитростью. Вместо того, чтобы заменять знаки ':=' на '=', просто удалим из каждого знака присваивания двоеточие.
var s:string;
i:integer;
begin
readln(s);
i:=pos(':=',s); {находим позицию первого знака присваивания}
while i<>0 do begin {открываем цикл для перебора всех знаков присваивания в строке}
Delete(s,i,1); {удаляем из знака присваивания двоеточие}
i:=pos(':=',s); {снова находим позицию знака присваивания. Так как предыдущий знак был изменен, то этим оператором мы найдем следующий знак присваивания}
end;
writeln(s);
readln;
end.
Задача 32. Дана строка символов и число N. Произвести ротацию строки на N символов (например: если исходная строка равна '1x2y3z4a', а N=3, то результирующая строка будет равна ' z4a1x2y3').
var s:string;
N:integer;
begin
readln(s);
readln(N);
n:=n mod length(s); {учитываем, что число N может быть больше, чем длина строки}
if n<>0 then begin
{с помощью вырезки составляем результирующую строку из двух частей исходной}
s:=copy(s,length(s)-n+1,n)+copy(s,1,length(s)-n);
end;
writeln(s);
readln;
end.