Мансуров. Основы программирования в среде Lazarus. 2010
.pdfГлава 3 Более сложные элементы языка
____________________________________________________________________
pred(ch) – возвращает предыдущий символ из кодовой таблицы; succ(ch) – возвращает следующий символ кодовой таблицы; upcase(ch) – преобразует строчную букву в заглавную. Работает только
для букв английского алфавита.
3.3.1.3. Тип String
Строкой называется некоторая последовательность символов: 'ААВВCC',
'Вася-это кот'.
Строка может состоять из нескольких символов, из одного символа, а мо-
жет быть совсем пустой. Максимальная длина строковой переменной зависит от директивы компилятора $H. Если включена директива {$H-}, то максималь-
ная длина строки 255 байтов, если же включена директива {$H+}, то длина строки практически неограниченна и может достигать до ~2 Гб.
Тип строковой переменной указывается зарезервированным словом string. Если заранее точно известна длина строки, например 30 символов,
то можно указать string[30].
Строковую переменную можно рассматривать как одно целое, а можно как массив символов, причем нумерация символов начинается с 0.
Пример описания строк и символов.
var Symbol: char;
Message: string;
Name: string[30];
Какие операции допустимы для строк и символов? Только операция сло-
жения. При этом в результате получается строка.
Пример:
program ch_str;
171
3.3Обработка символьной информации в Паскале
____________________________________________________________________
{$mode objfpc}{$H+} uses
CRT, FileUtil; var
Symbol: Char;
Mum, Str: string;
begin
Symbol:='A'; // это буква A латинского алфавита
Str:= 'Ш';
Str:= Str + Symbol;
Mum:= 'МАМА';
Mum:= Mum + Str;
{теперь Mum = 'МАМАШA '}
writeln(UTF8ToConsole(Mum));
Str:= ' ПАПАША = ПРЕДКИ';
Mum:= Mum + ' +' + Str;
{теперь Mum = 'МАМАШA + ПАПАША = ПРЕДКИ '}
writeln(UTF8ToConsole(Mum));
writeln(UTF8ToConsole('Нажмите любую клавишу'));
readkey;
end.
Обратите внимание, если вы в операторе
Symbol:='A';
укажете русскую букву 'А', то компилятор выдаст ошибку!
Как уже отмечалось, в Lazarus и FPC используется кодировка UTF8. В этой кодировке для представления кириллических символов используются два бай-
та. Таким образом, переменной типа char нельзя присвоить значение кирил-
172
Глава 3 Более сложные элементы языка
____________________________________________________________________
лицы. Если вы все же хотите использовать символы кириллицы в символьных переменных, то используйте тип TUTF8Char, как в следующем примере.
Пример:
program ch_str; {$mode objfpc}{$H+} uses
CRT, FileUtil, LCLType; var
Symbol: TUTF8Char; // новый тип, введенный в FPC
Mum, Str: string; begin
Symbol:='А'; // это русская буква А, занимает в памяти два байта
Str:= 'Ш';
Str:= Str + Symbol;
Mum:= 'МАМА';
Mum:= Mum + Str;
{теперь Mum = 'МАМАШA '}
writeln(UTF8ToConsole(Mum));
Str:= ' ПАПАША = ПРЕДКИ';
Mum:= Mum + ' +' + Str;
{теперь Mum = 'МАМАШA + ПАПАША = ПРЕДКИ '}
writeln(UTF8ToConsole(Mum));
writeln(UTF8ToConsole('Нажмите любую клавишу'));
readkey;
end.
Заметьте, что в строковых переменных (типа string) под символы латиницы
(коды которых меньше 128 в таблице ASCII) отводится один байт, а под симво-
лы кириллицы отводится два байта!
Следующая программа имитирует процесс авторизации пользователя для
173
3.3Обработка символьной информации в Паскале
____________________________________________________________________
входа в систему. Для этого пользователь должен ввести правильный пароль.
Если после трех попыток правильный пароль не будет введен, пользователю будет запрещен доступ в систему.
program password; {$mode objfpc}{$H+} uses
CRT, FileUtil, LConvEncoding; var
answ, passw: string; n: integer;
begin
passw:= 'абвг'; n:= 1;
repeat
writeln(UTF8ToConsole('Введите пароль')); readln(answ);
{$IFDEF WINDOWS}
answ:= CP866ToUTF8(answ); // преобразование введенной
// строки к UTF8
{$ENDIF}
if answ <> passw then begin
if n = 1 then begin
writeln(UTF8ToConsole('Вы не пользователь'));
inc(n);
end
else
174
Глава 3 Более сложные элементы языка
____________________________________________________________________
begin
if n = 3 then
begin
writeln(UTF8ToConsole('Вам отказано в доступе'));
break;
end
else
begin
writeln(UTF8ToConsole('Вы не пользователь')); writeln(UTF8ToConsole('Вы '), n, UTF8ToConsole('-раз ввели неправильный пароль')); writeln(UTF8ToConsole('После 3-й попытки вам ')); writeln(UTF8ToConsole('будет отказано в доступе'));
inc(n);
end
end
end
else
writeln(UTF8ToConsole('Здравствуйте, вы вошли в систему!'));
until answ = passw;
writeln(UTF8ToConsole('Нажмите любую клавишу'));
readkey;
end.
В этой программе мы использовали функцию CP866ToUTF8() для пре-
образования введенной с клавиатуры строки к UTF-8. Разумеется, это касается только пользователей Windows, так как мы уже неоднократно отмечали, что в консоли Windows используется кодировка CP866. Функция CP866ToUTF8()
описана в модуле LConvEncoding.
Обратите внимание на директивы компилятора для условной компиляции
175
3.3Обработка символьной информации в Паскале
____________________________________________________________________
{$IFDEF WINDOWS}
answ:= CP866ToUTF8(answ);
{$ENDIF}
Директива {$IFDEF <условие>} предписывает компилятору компили-
ровать операторы, находящиеся после нее и до {$ENDIF} если <условие>
выполняется. В противном случае эти операторы пропускаются. В данном слу-
чае оператор
answ:= CP866ToUTF8(answ);
будет включен в компиляцию в операционной системе Windows и будет про-
пущен в Linux. Полная форма этой директивы:
{$IFDEF <условие>}
<операторы> // компилируются, если <условие> выполнено
{$ELSE}
<операторы> // компилируются, если <условие> не выполнено
{$ENDIF}
3.3.1.4. Строковые процедуры и функции
Функция Concat- выполняет конкатенацию последовательности строк,
т. е. объединение нескольких строк.
Описание: Concat(S1[,S2,…,Sn]: string): string;
S1,S2,…,Sn – формальные параметры, имеют тип string. Квадратные скобки указывают, что параметры S2,…,Sn могут отсутствовать. Результат функции строка символов, т.е. имеет тип также string.
Пример:
176
Глава 3 Более сложные элементы языка
____________________________________________________________________
program function_concat; {$mode objfpc}{$H+} uses
Crt, FileUtil; var
a, c: string; begin
a:= 'Коля + Оля'; writeln(UTF8ToConsole('Первая строка: '),
UTF8ToConsole(a));
c:= ' = любовь';
writeln(UTF8ToConsole('Вторая строка: '),
UTF8ToConsole(c));
c:= Concat(a, c);
writeln(UTF8ToConsole('Результирующая строка: '),
UTF8ToConsole(c));
writeln(UTF8ToConsole('Нажмите любую клавишу'));
readkey;
end.
Функция Length - возвращает динамическую длину строки.
Описание: Length(S: string): integer;
Пример:
program function_length; {$mode objfpc}{$H+} uses
CRT, FileUtil, SysUtils; var
S: string;
177
3.3Обработка символьной информации в Паскале
____________________________________________________________________
i: integer;
begin
S:= 'Ivanov';
i:= Length(S);
writeln(UTF8ToConsole('Строка S: '), UTF8ToConsole(S)); writeln(UTF8ToConsole('Длина этой строки = '), i);
S:= '';
i:= Length(S);
writeln(UTF8ToConsole('Строка S: '), UTF8ToConsole(S)); writeln(UTF8ToConsole('Теперь длина строки стала = '), i); writeln(UTF8ToConsole('Нажмите любую клавишу'));
readkey;
end.
Следует помнить, что функция Length()возвращает количество байтов,
занимаемой строкой! В этом легко убедиться, немного видоизменив предыду-
щую программу.
program function_length; {$mode objfpc}{$H+} uses
CRT, FileUtil, SysUtils; var
S, S1: string; i: integer;
begin
S:= 'Ivanov'; i:= Length(S);
writeln(UTF8ToConsole('Строка S: '), UTF8ToConsole(S)); writeln(UTF8ToConsole('Длина этой строки = '), i);
178
Глава 3 Более сложные элементы языка
____________________________________________________________________
S1:= 'Иванов';
i:= Length(S1);
writeln(UTF8ToConsole('Строка S1: '), UTF8ToConsole(S1)); writeln(UTF8ToConsole('Длина этой строки = '), i); writeln(UTF8ToConsole('Нажмите любую клавишу'));
readkey;
end.
Длина строки S равна 6, длина строки S1 равна 12! Это не ошибка, про-
сто функция Length()возвращает не количество символов в строке, а количе-
ство байтов, которую занимает строка в памяти. Для латиницы это получается одно и то же, поскольку в UTF-8 символы латиницы кодируются одним байтом,
а для кириллицы в два раза больше, так как русские буквы кодируются двумя байтами. Если вы хотите получить количество символов в строке с кириллицей,
можно воспользоваться функцией UTF8Length(). Эта функция объявлена в модуле LCLProc.
Замените в предыдущем примере оператор
i:= Length(S1);
на оператор
i:= UTF8Length(S1);
и добавьте модуль LCLProc в объявление uses и запустите заново про-
грамму. Теперь длина строки S1 также стала равна 6.
Попробуйте заменить оператор
i:= Length(S);
на оператор
i:= UTF8Length(S);
Вы увидите, что длина строки S по-прежнему равна 6. Т.е. функция
UTF8Length() для строк с латиницей работает идентично функции
Length(). Отсюда можно сделать вывод, что удобнее применять функцию
179
3.3Обработка символьной информации в Паскале
____________________________________________________________________
UTF8Length(), особенно, если вам заранее неизвестно содержимое строки.
Процедура SetLength - устанавливает длину строки.
Описание:
SetLength(S: string, n: integer);
S – строка, n – новая длина строки. Если строка состоит из кирилли-
цы, то необходимо n умножать на 2. А если строка содержит символы и кирил-
лицы и латиницы, то придется высчитывать, сколько символов кириллицы со-
держится в строке. Так что, без особой необходимости применять эту функцию не стоит.
Функция Copy – возвращает подстроку строки.
Описание:
Copy(S: string, index, count: integer): string;
S- исходная строка,
index - номер символа, начиная с которого выделяется подстрока из S, count - количество символов в подстроке.
В модуле LCLProc имеется аналог этой функции UTF8Copy().
Пример:
program function_copy; {$mode objfpc}{$H+} uses
CRT, FileUtil, LCLProc; var
a, c: string; begin
180