7.3.2. Нуль-терминальные
строки
Нуль-терминальные строки широко используются
при обращениях к так называемым API-функциям Windows (API - Application Program
Interface - интерфейс прикладных программ). Поскольку компоненты Delphi берут
на себя все проблемы связи с API-функциями Windows, программисту редко приходится
прибегать к нуль-терминальным строкам. Тем не менее в этом разделе описываются
особенности обработки таких строк.
Прежде всего напомню, что базовый
тип string хранит в памяти терминальный нуль, поэтому Object Pascal допускает
смешение обоих типов в одном строковом выражении, а также реализует взаимное
приведение типов с помощью автофункций преобразования String и PChar. Например:
procedure
TfmExample.FormActivate(Sender: TObject);
var
pcS: PChar;
ssS:
String;
begin
pcS := '123456';
ssS := 'X = ';
IbOutput.Caption
:=
ssS
+ pcS;
end;
В строке IbOutput будет выведено
х = 123456. Другой пример. В состав API-функцией входят функция MessageBox,
с помощью которой на экране создается диалоговое окно с заголовком, текстовым
сообщением и набором кнопок. Если в конце предыдущего примера добавить оператор
MessageBox(0, ssS + pcS,
'Заголовок окна', mb_0k);
то компилятор укажет на ошибку, т.
к. вторым параметром обращения к функции должно быть выражение типа PChar, в
то время как выражение sss+pcs приводится компилятором к общему типу String.
Правильным будет такое обращение:
MessageBox(0, PChar (ssS
+ pcS), 'Заголовок окна', mb_0k) ;
Текстовые константы совместимы с
любым строковым типом, поэтому третий параметр обращения (он тоже должен быть
типа PChar) компилятор обработает без ошибок.
В Delphi считается совместимым с
pchar и string массив символов с нулевой нижней границей. В отличие от pchar
и String такой массив распределяется статически (на этапе компиляции), поэтому
наполнение массива символами и завершающим нулем осуществляется специальной
процедурой Strcopy:
procedure
TfmExample.bbRunClick(Sender:TObject);
var
acS:
array
[0..6]
of Char;
begin
StrCopy(acS, '123456');
IbOutput.Caption := acS;
end;
Для работы с типом pchar используются
такие же операции, как и с типом String: операция конкатенации “+” и операции
сравнения >, >=, <, <=, =, <>.
Таблица 7.13. Подпрограммы
для работы с нуль-терминальными строками
Function CharToOem
(Str, OemStr: PChar):
Bool;
|
Преобразует символы строки
Str из кодировки ANSI в кодировку MS-DOS и помещает результат в OemStr.Всегда
возвращает True
|
Function CharToOemBuff(Str,
OemStr: PChar; MaxLen: Lorigint): Bool;
|
Преобразует не более MaxLen
символов строки Str из кодировки ANSI в кодировку MS-DOS и помещает результат
в OemStr. Всегда возвращает True
|
Function OemToChar (OEMStr,
Str: PChar): Bool;
|
Преобразует символы из кодировки
MS-DOS в кодировку ANSI и возвращает True
|
Function OemToCharBuff(OEMStr,
Str: PChar;MaxLen: Longint): Bool;
|
Преобразует не более MaxLen
символов строки OemStr из кодировки MS-DOS в кодировку ANSI и помещает
результат в Str. Всегда возвращает True
|
Function StrCat(Dest,Source:
PChar): PChar;
|
Копирует строку Source в конец
строки Dest и возвращает указатель на строку Dest
|
Function StrComp (Strl,Str2:
PChar): Integers;
|
Побайтно сравнивает строку
Strl со строкой Str2 и возвращает следующий результат: =0 для Strl=Str2;
>0 для Strl>Str2,- 0 для Strl<Str2
|
Function StrCopy(Dest,Source:
PChar): PChar;
|
Копирует строку Source в строку
Dest и возвращает указатель на Dest. StrCopy не проверяет реальный размер
памяти, связанный с Dest (он должен быть не меньше StrLen(Source)+1)
|
Procedure StrDispose(Str: PChar)
;
|
Удаляет строку Str из памяти.
Строка должна быть предварительно помещена в память функцией StrNew. Если
Str=NlL, процедура ничего не делает
|
Function StrECopy(Dest, Source:
PChar): PChar;
|
Объединяет строки. Эта функция
работает в точности, как StrCat, но возвращает указатель на конец сцепленных
строк, т. е. на терминальный ноль
|
Function StrEnd(Str:
PChar): PChar;
|
Функция возвращает указатель
на терминальный нольстроки Str
|
Function StrIComp(Strl,Str2:
PChar): PChar;
|
Функция сравнивает строки,
игнорируя возможную разницу в высоте букв. Возвращает такой же результат,
как и StrComp. Замечу, что функция правильно работает лишь с латиницей.
Для кириллицы ее нужно модифици ровать (см.ниже)
|
Function StrLCat(Dest,Source:
PChar; MaxLen:Word): PChar;
|
Копирует символы строки Source
в конец строки Dest до тех пор, пока не будут скопированы все символы
или пока длина сцепленной строки Dest не достигнет MaxLen. Возвращает
указатель на сцепленную строку. В отличие от StrCopy эта функция блокирует
возможноепереполнение области памяти, связанной с Dest. Обычно в качестве
MaxLen используется выражение SizeOf(Dest)-!
|
Function StrLComp(Dest,
Source: PChar; MaxLen:
Word): PChar;
|
В отличие от StrComp сравнивает
не более MaxLen символов строк. Возвращаемый результат такой же, как и
у StrComp
|
Function StrLCopy(Dest,
Source: PChar; MaxLen:
Word): PChar;
|
Копирует символы из строки
Source в строку Dest до тех пор, пока не будет скопирована вся строка
или пока не будет скопировано MaxLen символов. В отличие от StrCopy блокирует
возможное переполнение области памяти, связанной с Dest. В качестве MaxLen
обычно используется выражение SizeOf(Dest)-1
|
Function StrLen(Str:PChar):
Cardinal;
|
Возвращает длину строки
|
Function StrLIComp(Strl, Str2:
PChar; MaxLen: Word): PChar;
|
Сравнивает не более MaxLen
символов строк, проверяя точное соответствие высоты букв. Возвращаемый
результат см. StrComp. Функция правильно работает только с латиницей
|
Function StrLower(Str:
PChar): PChar;
|
Преобразует заглавные буквы
строки Str к строчным и возвращает указатель на результат. Функция правильно
работает только с латиницей
|
Function S t rMove(Dest,
Source: PChar; Count:Word):
PChar;
|
Копирует точно Count символов
строки Source в строку Dest и возвращает указатель на результат. Функция
игнорирует действительные размеры строк и может выйти за их пределы
|
Function StrNew(Str:PChar):
PChar;
|
Помещает строку в память
|
Function StrPas(Str:PChar):
String;
|
Преобразует нуль-терминальную
строку в строку String
|
Function StrPCopytStr: PChar;
S: String):PChar;
|
Преобразует строку String в
нуль-терминальную строку. Возвращает указатель на Str
|
Function StrPos(Strl,
Str2: PChar): PChar;
|
Ищет подстроку Str2 в строке
Strl и возвращает указатель на первое вхождение Str2 или MIL, если подстрока
не найдена
|
Function StrRScan(Str:
PChar; Ch: Char):PChar;
|
Ищет символ Ch в строке Str
и возвращает указатель напоследний обнаруженный символ Ch или NIL, если
символ не найден
|
Function StrScan(Str:PChar;
Ch: Char):PChar;
|
Ищет символ Ch в строке Str
и возвращает указатель на первый обнаруженный символ Ch или MIL, если
символ не найден
|
Function StrUpper (Str: PChar)
: PChar
|
Преобразует строчные буквы
строки Str к заглавным и возвращает указатель на результат. Функция правильно
работает только с латиницей
|
Функции преобразования из ANSI-кодировки
в кодировку MS-DOS (charToxxx) и обратно (OеmTоххх) правильно работают с кириллицей,
если в MS-DOS используется национальная страница 866 (так называемая альтернативная
кодировка). А вот четыре функции, использующие преобразование высоты букв (strLower,
StrUpper, Stricomp и StrLIComp), работают корректно только для букв латинского
алфавита (латиницы). Для русских букв вместо обращения к
этим
функциям следует использовать стандартные функции AnsiLowerCase И AnsiUpperCase,
которые используют как параметры String, так и PChar, но возвращают результат
типа string:
var
acS:
array
[Byte]
of Char;
begin
StrCopy(acS, 'заглавные
буквы');
Caption := AnsiUpperCase(acS)
end;
Аналогично для функции Stricomp:
var
apSl,apS2:
array
[0..1000] of Char;
begin
StrCopy(apSl,'эталон');
StrCopy(apS2,'ЭТАЛОН') ;
Caption := IntToStr(StrIComp(PChar(AnsiUpperCase(apSl)),
PChar(AnsiUpperCase(apS2))))
end;