TURBO PASCAL |
Новости
|
Длинные строки
Среда Турбо Паскаль 7.0 обладает весьма интересным новшеством: в ней введена поддержка длинных строк, т.е. строк, длина которых может превышать 255 байт. Как известно, тип String в Турбо Паскале имеет максимальную длину 255 байт. Это связано с тем, что истинная длина строки в этом типе указывается первым байтом, мощность которого не позволяет определять строки большей длины. В то же время в языке С используется другой подход к заданию текстовых строк: первый байт строки является ее первым символом, второй байт - вторым символом и т.д. пока не встретится байт с символом #0. Таким образом, длина строки не указывается явно, как в типе String, а определяется по замыкающему символу #0. Ясно, что такие строки могут иметь произвольную длину, ограничиваемую лишь объемом оперативной памяти или принятой схемой ее адресации: в MS-DOS такой границей является длина сегмента, поэтому максимально возможная длина С-строки для ПК составляет 65535 символов. Такие строки в дальнейшем будем называть ASCIIZ-строками. Для реализации операций над ASCIIZ-строками в язык введен новый тип PChar, определяемый как указатель на символ: type PChar =Char; Однако такой обычный для Паскаля тип-указатель в рамках Турбо Паскаля 7.0 трактуется необычным способом: считается, что он указывает на цепочку символов, заканчивающуюся терминальным нулем, т.е. на ASCIIZ-строку. Более того, с этим типом совместим любой одномерный символьный массив с нулевой левой границей, а переменные типа PChar можно индексировать, как если бы они были массивами символов. Следующая программа напечатает все заглавные буквы английского алфавита: {$Х+} {Включаем расширенный синтаксис} var Chars : array [0..26] of Char; {Массив символов} PChars: PChar; {Указатель на символ} k : Integer; begin for k := 0 to 25 do Chars[k] := Chr(k+ord('A'); {Наполняем массив} PChars := Chars; {Указателю присваиваем массив!} PChars[26] := #0; {Индексируем указатель!} WriteLn(PChars) {Печатаем указатель!} end. Три последние оператора программы недопустимы в стандартном Паскале и в ранних версиях Турбо Паскаля, но возможны в версии 7.0, если включен расширенный синтаксис (директивой {$Х+} или опцией Options/Compiler/Extended syntax). Обратите внимание: процедура WriteLn этой версии умеет работать с ASCIIZ-строками. Для поддержки ASCIIZ-строк разработан модуль Strings, в котором реализованы необходимы процедуры и функции. Функция StrCat. Объединяет строки. Заголовок: Function StrCat(Dest, Source: PChar): PChar; Копирует строку Source в конец строки Dest и возвращает указатель на начало Dest. Функция StrComp. Сравнивает строки. Заголовок: Function StrComp(Strl, Str2: PChar): Integer; Побайтно сравнивает строку Strl со строкой Strl и возвращает следующий результат: =0 Strl=Str2; >0 Strl>Str2; <0 Strl<Str2. Функция StrCopy. Копирует строку. Заголовок: Function StrCopy(Dest, Source: PChar): PChar; Копирует строку Source в строку Dest и возвращает указатель на Dest. StrCopy не проверяет реальный размер памяти, связанный с Dest (он должен быть не меньше StrLen(Source)+1). Процедура StrDispose. Удаляет строку из кучи. Заголовок: Procedure StrDispose(Str: PChar); Строка Str должна быть предварительно помещена в кучу функцией StrNew. Если Str=NIL, процедура ничего не делает. Функция StrECopy. Объединяет строки. Заголовок: Function StrECopy(Dest, Source: PChar): PChar; Эта функция работает в точности как StrCat, но возвращает указатель на конец сцепленных строк, т.е. на терминальный ноль. Функция StrEnd. Возвращает конец строки. Заголовок: Function StrEnd(Str: PChar): PChar; Функция возвращает указатель на терминальный ноль ASCIIZ-строки Str. Функция StrlComp. Сравнивает строки. Заголовок: Function StrlComp(Strl, Str2: PChar): PChar; . Функция сравнивает строки, игнорируя возможную разницу в высоте букв. Возвращает такой же результат, как и StrComp. Замечу, что функция правильно работает лишь с латиницей. Для кириллицы ее нужно модифицировать (см. ниже). Функция StrLCat. Объединяет строки. Заголовок: Function StrLCat(Dest, Source: PChar; MaxLen: Word): PChar; Копирует символы строки Source в конец строки Dest до тех пор, пока не будут скопированы все символы или когда длина сцепленной строки Dest не достигнет MaxLen. Возвращает указатель на сцепленную строку. В отличие от StrCopy эта функция блокирует возможное переполнение области памяти, связанной с Dest. Обычно в качестве MaxLen используется выражение SizeOf (Dest) -1. Например: {$Х+} Uses Strings; var S: array [0..9] of Char; begin StrCopy(S, 'Turbo'); StrLCat(S, ' ', SizeOf(S)-1); StrLCat(S, 'Pascal', SizeOf(S)-1); WriteLn(S) {Напечатает "Turbo Pas"} end; Функция StrLComp. Сравнивает строки. Заголовок: Function StrLComp(Dest, Source: PChar; MaxLen: Word): PChar; В отличие от StrComp сравнивает не более MaxLen символов строк. Возвращаемый результат такой же, как и у StrComp. Функция StrLCopy. Заголовок: Function StrLCopy(Dest, Source: PChar; MaxLen: Word): PChar; Копирует символы из строки Source в строку Dest до тех пор, пока не будет скопирована вся строка или пока не будет скопировано MaxLen символов. В отличие от StrCopy блокирует возможное переполнение области памяти, связанной с Dest. В качестве MaxLen обычно используется выражение SizeOf (Dest) -1. Например: {$Х+} Uses Strings; var S: array [0..9] of Char; begin StrLCopy(S, 'Turbo Pascal', SizeOf(S)-1); WriteLn(S) {Напечатает "Turbo Pas"} end; Функция StrLen. Возвращает длину строки. Заголовок: Function StrCattStr: PChar): Word; Функция StrLIComp. Сравнивает строки с учетом регистра. Заголовок: Function StrLIComp(Str1, Str2: PChar; MaxLen: Word): PChar; Сравнивает не более MaxLen символов строк, проверяя точное соответствие высоты букв. Возвращаемый результат см. StrComp. Функция правильно работает только с латиницей. Функция StrLower. Преобразует в строчные буквы. Заголовок: Function StrLower(Str: PChar): PChar; Преобразует заглавные буквы строки Str к строчным и возвращает указатель на результат. Функция правильно работает только с латиницей. Функция StrMove. Копирует строку. Заголовок: Function StrMove(Dest, Source: PChar; Count: Word): PChar; Копирует точно Count символов строки Source в строку Dest и возвращает указатель на результат. Функция игнорирует действительные размеры строк и может выйти за их пределы. Функция StrNew. Помещает строку в кучу. Заголовок: Function StrNew(Str: PChar): PChar; Функция Str Pas. Преобразует ASCHZ-строку в строку String. Заголовок: Function StrPas(Str: PChar,) : String; Функция StrPCopy. Преобразует строку String в ASCIIZ-строку. Заголовок: Function StrPCopy(Str: PChar; S: String): PChar; Возвращает указатель на Str. Функция StrPos. Ищет подстроку. Заголовок: Function StrPos(Strl, Str2: PChar): PChar; Ишет подстроку Str2 в строке Strl и возвращает указатель на первое вхождение Str2 или NIL, есди подстрока не найдена. Функция StrRScan. Ищет последний символ. Заголовок: Function StrRScan(Str: PChar; Ch: Char): PChar; Ищет символ Ch в строке Str и возвращает указатель на последний обнаруженный символ Ch или NIL, если символ не найден. Функция StrScan. Ищет первый символ. Заголовок: Function StrScan(Str: PChar; Ch: Char): PChar; Ищет символ Ch в строке Str и возвращает указатель на первый обнаруженный символ Ch или NIL, если символ не найден. Функция StrUpper. Заголовок: Function StrLower(Str: PChar): PChar; Преобразует строчные буквы строки Str к заглавным и возвращает указатель на результат. Функция правильно работает только с латиницей. Четыре функции модуля Strings (StrLower, StrUpper, StrlComp и StrLIComp) используют преобразование высоты букв и работают корректно только для букв латинского алфавита (латиницы). Для русских букв эти функции можно изменить следующим образом: {Этот модуль содержит модификацию функций стандартного модуля Strings для работы с кириллицей (альтернативный вариант кодировки} {$Х+} Unit StringsR; INTERFACE Function LoCase(Ch: Char): Char; Function UpCase(Ch: Char): Char; Function StrLower(Str: PChar): PChar; Function StrUpper(Str: PChar): PChar; Function StrlComp(Strl, Str2: PChar): Integer; Function StrLIComp(Strl, Str2: PChar; MaxLen: Word): Integer; IMPLEMENTATION Uses Strings; Function LoCase(Ch: Char): Char; {Преобразует латинскую или русскую букву Ch к строчной} begin case Ch of 'A' . .'Z':LoCase:= Chr(ord('a')+ord(Ch)-ord('A')); 'A' . .'П':LoCase:= Chr(ord('a')+ord(Ch)-ord('A')); 'P' . .'Я':LoCase:= Chr(ord('p')+ord(Ch)-ord('P')); else LoCase:= Ch end end; {-------------------} Function UpCase(Ch: Char): Char; {Преобразует латинскую или русскую букву Ch к заглавной} begin case Ch of 'a'..'z': UpCase := Chr(ord('A')+ord(Ch)-ord('a')); 'a'..'n': UpCase := Chr(ord('A')+ord(Ch)-ord('a')); 'p'..'я': UpCase := Chr(ord('P')+ord(Ch)-ord('p')); else UpCase:= Ch end end; {-------------} Function StrLower(Str: PChar): PChar; {Преобразует латинские и русские буквы строки Str к строчным} var k: Word; begin for k := 0 to StrLen(Str)-1 do Str[k]:= LoCase(Str[k]); StrLower:= Str end; {-----------} Function StrUpper(Str: PChar): PChar; {Преобразует латинские и русские буквы строки Str к заглавным} var k: Word; begin for k :=0 to StrLen(Str)-1 do Str[k]:= UpCase(Str[k]); StrUpper:= Str end; {------------} Function StrlComp (Str1, Str2 : PChar): Integer; {Сравнивает две строки, игнорируя возможную разницу в высоте латинских или русских букв} var k: Word; Max: Word; begin {Определяем максимальное количество сравниваемых символов как минимум длин строк} Мах := StrLen(Str1) ; if StrLen (Str2).<Max then Max := StrLen(Str2) ; {Проверяем символы до первого несовпадения.Буквы преобразуем к заглавным} for k := 0 to Max-1 do if UpCase(Strl[k])<>UpCase(Str2[k]) then begin {Строки не равны} StrIComp := ord(UpCase(StrlCk]))-ord(UpCase(Str2[k])); Exit end; {Разницы нет - результат зависит от совпадения длин} StrIComp := StrLen(Str1)-StrLen(Str2) end; {--------------} Function StrLIComp(Str1, Str2: PChar; MaxLen: Word): Integer; {Сравнивает не более MaxLen символов строк, проверяя точное соответствие высоты букв} var k. Max: Word; begin {Определяем максимальное количество сравниваемых символов как минимум длин строк и MaxLen} Мах := MaxLen; if StrLen(Strl)<Max then Max := StrLen(Strl); if StrLen(Str2)<Max then Max := StrLen(Str2); {Проверяем символы до первого несовпадения.Буквы преобразуем к заглавным} for k := 0 to Max do if UpCase(Str1 [k])<>UpCase(Str2[k]) then begin StrLIComp := ord(UpCase(Str1[k]))-ord(UpCase(Str2[k])); Exit end; {Разницы нет. Если проверено MaxLen символов, строки считаются равными, в противном случае результат зависит от совпадения длин строк} if Max=MaxLen then StrLIComp := 0 else StrLIComp := StrLen(Str1)-StrLen(Str2) end; end. Если Вы будете использовать этот модуль, ссылайтесь на него в предложении Uses после ссылки на стандартный модуль Strings: Uses Strings, StringsR, ...
|
(с)Все права защищены По всем интересующим вопросам прошу писать на электронный адрес |