CompareStr — Функция Delphi


CompareStr — Функция Delphi

почему код CompareStr и StrComp отличается? я не силён в ассемблере, но по-моему код отличается не в плане отличий AnsiString от PChar (которые судя по _LStrToPChar минимальны), а в плане алгоритма сравнения. зачем две функции для одной задачи? и, главное, будут ли их результаты одинаковыми для любых входных строк?

может кто-нибудь, знающий ассемблер, переведёт их код на паскаль чтобы сравнить поведение?


> код отличается не в плане отличий AnsiString от PChar

Именно в этом плане и все принципиальные отличия между алгоритмами этих функций.

> Сергей М. (05.07.2007 17:20:01) [1]

Вот более серьезное различие

StrComp — Note: When working with International characters, use AnsiStrComp instead.

CompareStr — The compare operation is based on the 8-bit ordinal value of each character and is not affected by the current locale.


> > код отличается не в плане отличий AnsiString от PChar
> Именно в этом плане и все принципиальные отличия между алгоритмами
> этих функций.

а в чём собственно отличие AnsiString и PChar?
AnsiString — ссылка на массив байт (символов) после которых стоит #0. по отрицательному смещению ещё есть 4 байта счётчика ссылок и 4 байта поля длины.
PChar — ссылка массив байт (символов) после которых стоит #0.
поправьте если я не прав. ну ещё конечно же компилятор сам выделяет\освобождает память для AnsiString, а для PChar нет, но в данном случае это некритично.


> Вот более серьезное различиеStrComp — Note: When working
> with International characters, use AnsiStrComp instead.CompareStr
> — The compare operation is based on the 8-bit ordinal value
> of each character and is not affected by the current locale.
>

и где отличие? CompareStr использует просто код символа для сравнения. StrComp тоже (судя по тому что есть AnsiStrComp, которая учитывает локаль).

в общем если бы я знал ассемблер я бы сам разобрался в отличиях работы, но т.к. я его не знаю :( приходится строить предположения. может кто-нибудь всё-таки переведёт на паскаль?

кстати, я говорил о BDS2006, сейчас посмотрел D7 — реализация StrComp отличается. в BDS2006 она более «хитрая».


> поправьте если я не прав

Прав, все так и есть на самом деле.

Ну а раз AnsiString содержит служебные поля, то CompareStr использует их для ускорения сравнения в ряде ситуаций с содержимым сравниваемых строк.

В BDS задействовали алгоритмы FastCode


> REA (06.07.07 10:08) [7]
> В BDS задействовали алгоритмы FastCode

угу, мне интересно, почему StrComp взяли из FastCode, a CompareStr нет, хотя она тоже есть в FastCode.


> почему StrComp взяли из FastCode, a CompareStr нет

чтобы могли почувствовать разницу?

CompareStringW function

Compares two character strings, for a locale specified by identifier.

Syntax

Parameters

Locale identifier of the locale used for the comparison. You can use the MAKELCID macro to create a locale identifier or use one of the following predefined values.

Flags that indicate how the function compares the two strings. For detailed definitions, see the dwCmpFlags parameter of CompareStringEx.

Pointer to the first string to compare.

Length of the string indicated by lpString1, excluding the terminating null character. This value represents bytes for the ANSI version of the function and wide characters for the Unicode version. The application can supply a negative value if the string is null-terminated. In this case, the function determines the length automatically.

Pointer to the second string to compare.

Length of the string indicated by lpString2, excluding the terminating null character. This value represents bytes for the ANSI version of the function and wide characters for the Unicode version. The application can supply a negative value if the string is null-terminated. In this case, the function determines the length automatically.

Return Value

Returns the values described for CompareStringEx.

Remarks

If your application is calling the ANSI version of CompareString, the function converts parameters via the default code page of the supplied locale. Thus, an application can never use CompareString to handle UTF-8 text.

Normally, for case-insensitive comparisons, CompareString maps the lowercase «i» to the uppercase «I», even when the locale is Turkish or Azerbaijani. The NORM_LINGUISTIC_CASING flag overrides this behavior for Turkish or Azerbaijani. If this flag is specified in conjunction with Turkish or Azerbaijani, LATIN SMALL LETTER DOTLESS I (U+0131) is the lowercase form of LATIN CAPITAL LETTER I (U+0049) and LATIN SMALL LETTER I (U+0069) is the lowercase form of LATIN CAPITAL LETTER I WITH DOT ABOVE (U+0130).

Разница между CompareStr и «=» для струнных инструментов в Delphi

Я просто хочу знать разницу между CompareStr и = для сравнения строк в Delphi. Оба дают одинаковый результат.

Как показывают сообщение палиндром.

Используйте CompareStr не тогда , когда вы просто хотите посмотреть , являются ли две строки равны, но если вы хотите знать , как одна строка сравнивается по отношению к другому. Она возвращает значение меньше 0 , если первый аргумент появляется первым, asciibetically, и он будет возвращать значение больше нуля , если первый аргумент принадлежит после того, как второй.

Без CompareStr , вы можете иметь такой код:

Это сопоставимо str1 и str2 дважды. С CompareStr , вы можете вырезать один из сравнения строк и заменить его более дешевым целочисленного сравнения:

Как ответ Джерри объясняет, функция особенно полезна в функции сортировки, тем более , что он имеет тот же интерфейс , как и другие функции сравнения , как CompareText и AnsiCompareStr . Функция сортировки является метод шаблона , а каждая из функций служит в качестве сравнения стратегии .

Если все , что вам нужно сделать , это тест на равенство, используйте = оператор — это легче читать. Используйте , CompareStr когда вы нуждаетесь в дополнительной функциональности он предоставляет.

Предполагая Str1 и Str2 являются строками, а не массивы (или списков) или строк, первая версия будет более эффективной, так как вторая версия будет первая копию str1[i] и str2[i] две новых строк, а затем вызвать функцию, с сопутствующими накладными расходами.

Первая версия будет просто сравнить отдельные символы, указанные на str1 [I] и str2 [я]

Если вы заинтересованы только если строки совпадают, использование = . Если вам нужно знать , если строки одинаковы, или какая строка больше, а затем использовать CompareStr .

CompareStr особенно полезно при сортировке списков, например, с помощью TList.Sort(CompareFunc) или TStringList.Sort(CompareFunc)

Если вы хотите сравнение без учета регистра, используйте CompareText.

Помимо возвращаемого значения (целое против булева), из кода он говорит, что для CompareStr «сравниваемая работа основана на 8-бит порядкового значение каждого символа и не зависит от текущей локали пользователя». Так это выглядит, как CompareStr первоначально была частью FASTCODE процедур и, в сущности, оптимизированную версию Ansi, разработанную для повышения производительности. Я всегда, как правило, идут с «=», « », и т.д.

CompareStr — Функция Delphi

Оба позволяют указать используемый языковой стандарт. Является ли Windows более «полной» из-за доступных флагов сравнения? Следовательно, один быстрее другого?

CompareStr (», loInvariantLocale) — это просто побайтовое сравнение символов в строке. CompareStr (», loUserLocale) вызывает внутреннюю функцию CompareString, поэтому они идентичны, за исключением дополнительных флагов, которые может принимать CompareString. Он также встроен, поэтому вы не должны видеть никакой разницы в скорости между ним и непосредственным вызовом CompareString.

CompareStr Routine

Unit Edit

Description Edit

Definition (Delphi 6):

Definition (Delphi 2010):

Technical Comments Edit

(Known issues / Documentation clarifications / Things to be aware of)

Examples Edit

(Please provide links to articles/source code that show how to use this item.)

See Also Edit

(Please provide links to items specifically related to this item.)

User Comments/Tips Edit

(Please leave your name with your comment.)

Разница между CompareStr и ‘=’ для строк в Delphi

Я просто хочу знать разницу между CompareStr и = для сравнения строк в Delphi. Оба дают тот же результат.

Оба показывают сообщение Palindrome.

Создан 23 июн. 11 2011-06-23 10:11:56 CyprUS

Вопрос о сравнении строк, но, судя по представленному вами коду, вы сравниваете символы. Трудно сказать, что здесь задавали. – kludg 23 июн. 11 2011-06-23 11:42:51

@Serg +1 Хорошая точка, я предположил, что ‘str1′ и’ str2′ были массивами строки. Но, может быть, нет . – David Heffernan 23 июн. 11 2011-06-23 11:44:57

4 ответа

Используйте CompareStr , когда вы просто хотите увидеть, равны ли две строки, но когда вы хотите знать, как одна строка сравнивается относительно другой. Он вернет значение меньше 0, если первый аргумент появится первым, асипически, и он вернет значение больше нуля, если первый аргумент принадлежит после второй.

Без CompareStr , вы могли бы иметь такой код:

Это сравнивает str1 и str2 дважды. С CompareStr , вы можете вырезать один из сравнения строк и заменить его более дешевым целочисленного сравнения:

As Gerry’s answer объясняет, функция особенно полезна в функции сортировки, тем более, что он имеет такой же интерфейс, как и другие сравнения функции, такие как CompareText и AnsiCompareStr . Функция сортировки — это template method, и каждая из функций служит для сравнения strategy.

Если все, что вы хотите сделать, это проверка равенства, используйте оператор = — его легче читать. Используйте CompareStr , если вам нужна дополнительная функциональность, которую он предоставляет.

Создан 23 июн. 11 2011-06-23 13:59:14 Rob Kennedy

Результат не совпадает, при сравнении строки не равны. Результат CompareStr или AnsiCompareStr имеет тип Integer, показывающий некоторую дополнительную информацию буквально, как эти строки сравниваются. Посмотрите на http://www.delphibasics.co.uk/RTL.asp?Name=AnsiCompareStr

Создан 23 июн. 11 2011-06-23 10:24:31 jszpilewski

вот оно? только тип результата отличается? Тогда это почти то же самое, я думаю – CyprUS 23 июн. 11 2011-06-23 10:30:05

Если я правильно помню ‘==’, используемый для вызова ‘CompareStr’ в более ранних версиях Delphi. – CodesInChaos 23 июн. 11 2011-06-23 10:38:37

@CodeInChaos: Delphi никогда не поддерживала непаскальные операторы вроде ==. – Gerry Coll 23 июн. 11 2011-06-23 11:08:07

@Gerry Очевидно, я имел в виду оператор сравнения ‘=’. – CodesInChaos 23 июн. 11 2011-06-23 11:15:12

@Chaos — извините, думал, что вы подразумеваете в качестве дополнительного оператора, например, === на некоторых языках. (возможно, симптоматичный плохой дизайн?)

Gerry Coll 23 июн. 11 2011-06-23 11:22:04

Помимо значения возврата (целое по сравнению с булевым), из кода он говорит, что для CompareStr операция сравнения основана на 8-битовом порядковом значении каждого символа и не зависит от текущий пользовательский язык «. Таким образом, похоже, что CompareStr изначально являлась частью процедур FastCode и, по сути, была оптимизированной версией Ansi, разработанной по соображениям производительности. Я всегда имел тенденцию идти с «=», « » и т. Д.

Создан 23 июн. 11 2011-06-23 10:36:21 Misha

CompareStr был создан не из FastCode. Первоначально это был Turbo Pascal. Delphi добавила AnsiCompareStr для учета разных кодовых страниц. FastCode улучшил CompareStr. – Rob Kennedy 23 июн. 11 2011-06-23 13:47:28

Да — проверенный временем с 80-х годов – DaveBoltman 23 окт. 17 2020-10-23 09:38:43

Предполагая, что Str1 и Str2 являются строками, а не массивами (или списками) или строкой, первая версия будет более эффективной, так как вторая версия сначала скопирует str1[i] и str2[i] в две новые строки, затем вызовет функцию с соответствующими служебными данными.

Первая версия будет просто сравнить отдельные символы, указанные на str1 [I] и str2 [я]

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

Илон Маск рекомендует:  Что такое код iis метабаза

CompareStr особенно полезно при сортировке списков, например, с TList.Sort(CompareFunc) или TStringList.Sort(CompareFunc)

Если вы хотите без учета регистра сравнения, используйте CompareText.

Создан 23 июн. 11 2011-06-23 11:16:40 Gerry Coll

+1 для ‘CompareText’. Нечувствительность к регистру, вероятно, будет самой важной причиной не использовать ‘=’. – jpfollenius 23 июн. 11 2011-06-23 20:53:13

Разница между CompareStr и ‘=’ для строк в Delphi

Я просто хочу знать разницу между CompareStr и = для сравнения строк в Delphi. Оба дают тот же результат.

Оба показывают сообщение Palindrome.

Создан 23 июн. 11 2011-06-23 10:11:56 CyprUS

Вопрос о сравнении строк, но, судя по представленному вами коду, вы сравниваете символы. Трудно сказать, что здесь задавали. – kludg 23 июн. 11 2011-06-23 11:42:51

@Serg +1 Хорошая точка, я предположил, что ‘str1′ и’ str2′ были массивами строки. Но, может быть, нет . – David Heffernan 23 июн. 11 2011-06-23 11:44:57

4 ответа

Используйте CompareStr , когда вы просто хотите увидеть, равны ли две строки, но когда вы хотите знать, как одна строка сравнивается относительно другой. Он вернет значение меньше 0, если первый аргумент появится первым, асипически, и он вернет значение больше нуля, если первый аргумент принадлежит после второй.

Без CompareStr , вы могли бы иметь такой код:

Это сравнивает str1 и str2 дважды. С CompareStr , вы можете вырезать один из сравнения строк и заменить его более дешевым целочисленного сравнения:

As Gerry’s answer объясняет, функция особенно полезна в функции сортировки, тем более, что он имеет такой же интерфейс, как и другие сравнения функции, такие как CompareText и AnsiCompareStr . Функция сортировки — это template method, и каждая из функций служит для сравнения strategy.

Если все, что вы хотите сделать, это проверка равенства, используйте оператор = — его легче читать. Используйте CompareStr , если вам нужна дополнительная функциональность, которую он предоставляет.

Создан 23 июн. 11 2011-06-23 13:59:14 Rob Kennedy

Результат не совпадает, при сравнении строки не равны. Результат CompareStr или AnsiCompareStr имеет тип Integer, показывающий некоторую дополнительную информацию буквально, как эти строки сравниваются. Посмотрите на http://www.delphibasics.co.uk/RTL.asp?Name=AnsiCompareStr

Создан 23 июн. 11 2011-06-23 10:24:31 jszpilewski

вот оно? только тип результата отличается? Тогда это почти то же самое, я думаю – CyprUS 23 июн. 11 2011-06-23 10:30:05

Если я правильно помню ‘==’, используемый для вызова ‘CompareStr’ в более ранних версиях Delphi. – CodesInChaos 23 июн. 11 2011-06-23 10:38:37

@CodeInChaos: Delphi никогда не поддерживала непаскальные операторы вроде ==. – Gerry Coll 23 июн. 11 2011-06-23 11:08:07

@Gerry Очевидно, я имел в виду оператор сравнения ‘=’. – CodesInChaos 23 июн. 11 2011-06-23 11:15:12

@Chaos — извините, думал, что вы подразумеваете в качестве дополнительного оператора, например, === на некоторых языках. (возможно, симптоматичный плохой дизайн?)

Gerry Coll 23 июн. 11 2011-06-23 11:22:04

Помимо значения возврата (целое по сравнению с булевым), из кода он говорит, что для CompareStr операция сравнения основана на 8-битовом порядковом значении каждого символа и не зависит от текущий пользовательский язык «. Таким образом, похоже, что CompareStr изначально являлась частью процедур FastCode и, по сути, была оптимизированной версией Ansi, разработанной по соображениям производительности. Я всегда имел тенденцию идти с «=», « » и т. Д.

Создан 23 июн. 11 2011-06-23 10:36:21 Misha

CompareStr был создан не из FastCode. Первоначально это был Turbo Pascal. Delphi добавила AnsiCompareStr для учета разных кодовых страниц. FastCode улучшил CompareStr. – Rob Kennedy 23 июн. 11 2011-06-23 13:47:28

Да — проверенный временем с 80-х годов – DaveBoltman 23 окт. 17 2020-10-23 09:38:43

Предполагая, что Str1 и Str2 являются строками, а не массивами (или списками) или строкой, первая версия будет более эффективной, так как вторая версия сначала скопирует str1[i] и str2[i] в две новые строки, затем вызовет функцию с соответствующими служебными данными.

Первая версия будет просто сравнить отдельные символы, указанные на str1 [I] и str2 [я]

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

CompareStr особенно полезно при сортировке списков, например, с TList.Sort(CompareFunc) или TStringList.Sort(CompareFunc)

Если вы хотите без учета регистра сравнения, используйте CompareText.

Создан 23 июн. 11 2011-06-23 11:16:40 Gerry Coll

+1 для ‘CompareText’. Нечувствительность к регистру, вероятно, будет самой важной причиной не использовать ‘=’. – jpfollenius 23 июн. 11 2011-06-23 20:53:13

Строковые типы в Delphi. Особенности реализации и использования

В этой статье будут освещены следующие вопросы:

  1. Какие строковые типы существуют в Delphi, и чем они отличаются друг от друга
  2. Преобразование строк из одного типа в другой
  3. Некоторые приемы использования строк типа AnsiString:
    1. Функции для работы со строками о которых многие часто забывают или вовсе не знают
    2. Передача строк в качестве параметров
    3. Использование строк в записях
    4. Запись в файл и чтение из файла
    5. Использование строк в качестве параметров и результатов функций размещенных в DLL.

Ну что, интересно? Тогда поехали.

Какие строковые типы существуют в Delphi, и чем они отличаются друг от друга?

В Delphi 1.0 существовал лишь единственный строковый тип String, полностью эквивалентный одноименному типу в Turbo Pascal и Borland Pascal. Однако, этот тип имеет существенные ограничения, о которых я расскажу позднее. Для обхода этих ограничений, в Delphi 2, разработчики из Borland устроили небольшую революцию. Теперь, начиная с Delphi 2, имеются три фундаментальных строковых типа: ShortString, AnsiString, и WideString. Кроме того, тип String теперь стал логическим. Т.е., в зависимости от настройки соответствующего режима компилятора (режим больших строк), он приравнивается либо к типу ShortString (для совместимости со старыми программами), либо к типу AnsiString (по умолчанию). Управлять режимом, можно используя директиву компиляции <$LONGSTRINGS ON/OFF>(короткая форма <$H+/->) или из окна настроек проекта – вкладка «Compiler» -> галочка «Huge strings». Если режим включен, то String приравнивается к AnsiString, иначе String приравнивается ShortString. Из этого правила есть исключение: если в определении типа String указан максимальный размер строки, например String[25], то, вне зависимости от режима компилятора, этот тип будет приравнен к ShortString соответствующего размера.

Поскольку, как вы узнаете в дальнейшем, типы ShortString и AnsiString имеют принципиальное отличие в реализации, то я вообще не рекомендую пользоваться логическим типом String без указания размера, если Вы, конечно, не пишете программ под Delphi 1. Если же Вы все-таки используете тип String, то я настоятельно рекомендую прямо в коде Вашего модуля указывать директиву компиляции, устанавливающую подразумеваемый Вами режим работы компилятора. Особенно если Вы используете особенности реализации соответствующего строкового типа. Если этого не сделать, то однажды, когда Ваш код попадет в руки другого программиста, не будет никакой гарантии того, что его компилятор будет настроен, так же как и Ваш.

Поскольку по умолчанию, после установки Delphi, режим больших строк включен, большинство молодых программистов даже и не подозревают, что String может представлять что-то отличное от AnsiString. Поэтому, дальше в этой статье, любое упоминание типа String без указания размера, подразумевает, что он равен типу AnsiString, если не будет явно указано иное. Т.е., считается что настройка компилятора соответствует настройке по умолчанию.

Сразу же упомяну о различии между типами AnsiString и WideString. Эти типы имеют практически одинаковую реализацию, и отличаются лишь тем, что WideString используется для представления строк в кодировке UNICODE использующей 16-ти битное представление каждого символа (WideChar). Эта кодировка используется в тех случаях когда необходима возможность одновременного присутствия в одной строке символов из двух и более языков (помимо английского). Например, строк содержащих одновременно символы английского, русского и европейских языков. За эту возможность приходится платить – размер памяти, занимаемый такими строками в два раза больше размера, занимаемого обычными строками. Использование WideString встречается не часто, поэтому, я буду в основном рассказывать о строках типа AnsiString. Но, поскольку они имеют одинаковую реализацию, почти все сказанное относительно AnsiString будет действительно и для WideString, естественно с учетом разницы в размере каждого символа.

Тоже самое касается и разницы между pChar и pWideChar.

Строковый тип AnsiString, обычно используется для представления строк в кодировке ANSI, или других (например OEM) в которых для кодирования одного символа используется один байт (8 бит). Такой способ кодирования называется single-byte character set, или SBCS. Но, очень многие не знают о существовании еще одного способа кодирования многоязычных строк (помимо UNICODE) используемого в системах Windows и Linux. Этот способ называется multibyte character sets, или MBCS. При этом способе, некоторые символы представляются одним байтом, а некоторые, двумя и более. В отличие от UNICODE, строки, закодированные таким способом, требуют меньше памяти для своего хранения, но требуют более сложной обработки. Так вот, строковый тип AnsiString может использоваться для хранения таких строк. Я не буду подробно останавливаться на этом способе кодирования, поскольку он применяется крайне редко. Лично я, ни разу не встречал программ использующих данный способ кодирования.

Знатоки Delphi вероятно мне сразу напомнят еще и о типах pChar (pWideChar) и array [. ] of Char. Однако, я считаю, что это не совсем строковые типы, но я расскажу и о них, поскольку они очень часто используются в сочетании со строковыми типами.

Итак, приведу основные характеристики строковых типов:

Тип Максимальный размер строки Размер переменной Объем памяти, требуемый для хранения строки
String[n] где 0 0, поэтому то Delphi и не освобождает память, занятую строкой.

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

Здесь, как мы уже знаем, после выполнения оператора s2 := s1, обе переменные указывают на один и тот же экземпляр строки ‘abc123’. Однако, что же произойдёт когда выполниться оператор s2[1] := ‘X’? Казалось бы, в единственном имеющимся в нашем распоряжении экземпляре строки первая буква будет заменена на ‘X’. И как следствие, обе строки станут равными ‘Xbc123’. s1 то за что «страдает»? Но, к счастью это не так. Здесь на помощь Delphi вновь приходит счетчик ссылок. Delphi, при выполнении этого оператора понимает, что строка на которую указывает s2 будет изменена, а это может повлиять на других. Поэтому, перед изменением строки, проверяется ее счётчик ссылок. Обнаружив, что на нее ссылается более одной строковой переменной, делается следующее: создается копия этой строки со счётчиком ссылок равным 1, и адрес этой копии, присваивается s2; У исходного экземпляра строки, счетчик ссылок уменьшается на 1 – ведь s2 на неё теперь не ссылается. И лишь после этого, происходит изменение первой буквы, теперь уже собственного экземпляра строки. Т.е., по окончанию выполнения этого оператора, в памяти будут находиться две строки: ‘abc123’ и ‘Xbc123’. Причем, s1 будет ссылаться на первую, а s2 на вторую.

При работе со строками определенными как константы, алгоритм работы несколько отличается. Приведу пример:

Казалось бы, при завершении работы процедуры, экземпляр строки ‘Вася’ должен быть уничтожен. Но в данном случае это не так. Ведь, при следующем входе в процедуру, для выполнения присваивания нужно будет вновь где-то взять строку ‘Вася’. Для этого, ещё при компиляции, Delphi размещает экземпляр строки ‘Вася’ в области констант программы, где её даже невозможно изменить, по крайней мере, простыми методами. Но как же при завершении процедуры определить что строка ‘Вася’ – константная строка, и ее нельзя уничтожать? Все очень просто. Для константных строк, счётчик ссылок устанавливается равным -1. Это значение, «выключает» нормальный алгоритм работы со «счётчиком ссылок». Он не увеличивается при присваивании, и не уменьшается при уничтожении переменной. Однако, при попытке изменения переменной (помните s2[1]:=’X’), значение счётчика равное -1 будет всегда считаться признаком того, что на строку ссылается более одной переменной (ведь он не равен 1). Поэтому, в такой ситуации всегда будет создаваться уникальный экземпляр строки, естественно, без декремента счётчика ссылок старой. Это защитит от изменений экземпляр строки-константы.

К сожалению, этот алгоритм срабатывает не всегда. Но об этом, мы поговорим позже, при рассмотрении вопросов преобразования строковых типов.

Где же Delphi хранит «счётчик ссылок»? Причем, для каждой строки свой! Естественно, вместе с самой строкой. Вот что представляет собой эта область памяти, хранящая экземпляр строки ‘abc’:

Байты с 1 по 4 Счётчик ссылок равный -1
Байты с 5 по 8 Длина строки равная 3
Байт 9 Символ ‘a’
Байт 10 Символ ‘b’
Байт 11 Символ ‘c’
Байт 12 Символ с кодом 0 (#0)

Для удобства работы с такой структурой, когда строковой переменной присваивается ссылка на эту строку, в переменную заносится адрес не начала этой структуры, а адрес её девятого байта. Т.е. адрес начала реальной строки (прямо как pChar). Для того, что бы приблизиться к реальной жизни, перепишем приведённую структуру:

Смещение Размер Значение Назначение
-8 4 -1 Счётчик ссылок
-4 4 3 Длина строки
1 ‘a’
1 1 ‘b’
2 1 ‘c’
3 1 #0

С полем по смещению -8, нам уже должно быть все ясно. Это значение, хранящееся в двойном слове (4 байта), тот самый счетчик, который позволяет оптимизировать хранение одинаковых строк. Значение этого счетчика имеет тип Integer, т.е. может быть отрицательным. На самом деле, используется лишь одно отрицательное значение – «-1», и положительные значения. 0 не используется.

Теперь, обратите внимание на поле, лежащее по смещению -4. Это, четырёхбайтовое значение длинны строки (почти как в ShortString). Думаю, Вы заметили, что размер памяти выделенной под эту строку не имеет избыточности. Т.е. компилятор выделяет под строку минимально необходимое число байт памяти. Это конечно хорошо, но, при попытке «нарастить» строку: s1 := s1 + ‘d’, компилятору, точнее библиотеке времени исполнения (RTL) придется перераспределить память. Ведь теперь строке требуется больше памяти, аж на целый байт. Для перераспределения памяти нужно знать текущий размер строки. Вероятно, именно для того, что бы не приходилось каждый раз сканировать строку, определяя её размер, разработчики Delphi и включили поле длины, строки в эту структуру. Длина строки, хранится как значение Integer, отсюда и ограничение на максимальный размер таких строк – 2 Гбайт. Надеюсь, мы не скоро упрёмся в это ограничение. Кстати, именно потому, что память под эти строки выделяется динамически, они и получили ещё одно свое название: динамические строки.

Осталось рассказать ещё о нескольких особенностях переменных AnsiString. Важнейшей особенностью значений этого типа является возможность приведения их к типу Pointer. Это впрочем, естественно, ведь в «душе» они и есть указатели, как бы они этого не скрывали. Например, если описаны переменные: s :AnsiString и p :Pointer. То выполнение оператора p := Pointer(s) приведет к тому, что переменная p станет указывать на экземпляр строки. Однако, при этом, очень важно знать: счетчик ссылок этой строки не будет увеличен. Но об этом, мы поговорим чуть позднее.

Поскольку, переменные этого типа реально являются указателями, то для них и реально такое значение как Nil – указатель в «никуда». Это значение в переменной типа AnsiString по смыслу приравнивается пустой строке. Более того, чтобы не тратить память и время на ведение счётчика ссылок, и поля размера строки всегда равного 0, при присваивании пустой строке переменной этого типа, реально, присваивается значение Nil. Это не очевидно, поскольку обычно не заметно, но как мы увидим позже, очень важная особенность.

Вот теперь, кажется, Вы знаете о строках все. Настала пора переходить к более интересной части статьи – как с этим всем жить?

Преобразование строк из одного типа в другой

Здесь, все как обычно, и просто и сложно.

Преобразование между «настоящими» строковыми типами String[n], ShortString, и AnsiString выполняются легко, и прозрачно. Никаких явных действий делать не надо, Delphi все сделает за Вас. Надо лишь понимать, что в маленькое большое не влезает. Например:

В результате выполнения этого кода, в переменной s3 окажется строка ‘abc’, а не ‘abcdef’. С преобразованием из pChar в String[n], ShortString, и AnsiString, тоже всё очень не плохо. Просто присваивайте, и все будет нормально.

Сложности начинаются тогда, когда мы начинаем преобразовывать «настоящие» строковые типы в pChar. Непосредственное присваивание переменным типа pChar значений строк не допускается компилятором. На оператор p := s где p имеет тип pChar, а s :AnsiString, компилятор выдаст сообщение: «Incompatible types: ‘String’ and ‘PChar'» — несовместимые типы ‘String’ и ‘PChar’. Чтобы избежать такой ошибки, надо применять явное приведение типа: p := pChar(s). Так рекомендуют разработчики Delphi. В общем, они правы. Но, если вспомнить, как хранятся динамические строки — с нулем в конце, как и pChar. А еще и то, что к AnsiString применимо преобразование в тип Pointer. Станет очевидным, что всего, возможно целых три способа преобразования строки в pChar:

Все они, синтаксически правильны. И кажется, что все три указателя (p1, p2 и p3) будут в результате иметь одно и то же значение. Но это не так. Всё зависит от того, что находится в s. Если быть более точным, равно ли значение s пустой строке, или нет:

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

Для выполнения преобразования pChar(s), компилятор генерит вызов специальной внутренней функции @LstrToPChar. Эта функция проверяет – если строковая переменная имеет значение Nil, то вместо него, она возвращает указатель на реально размещенную в памяти пустую строку. Т.е. pChar(s) никогда не вернет указатель равный Nil.

Тут все просто, такое преобразование просто возвращает содержимое строковой переменной. Т.е. если она при пустой строке содержит Nil, то и результатом преобразования будет Nil. Если же строка не пуста, то результатом будет адрес экземпляра строки.

Здесь, все совсем по другому. Перед выполнением такого преобразования, компилятор вставляет код, обеспечивающий ситуацию, когда указатель, хранящийся в s, будет единственным указателем на экземпляр строки в памяти. В нашем примере, если строка не пуста, то будет создана копия исходной строки. Вот ее-то адрес и будет возвращен как результат такого преобразования. Но, если строка пуста, то результатом будет Nil, как и во втором случае.

Теперь, интересно отметить, что если в приведенном примере, преобразование p3 := @(s[1]) выполнить первым, то при не пустой строке в s, все указатели (p1, p2, и p3), будут равны. И содержать они будут адрес «персонального» экземпляра строки.

Вот, теперь, зная как выполняются те или иные преобразования, Вы сможете всегда выбрать подходящий способ. Для тех, кто ещё не «проникся» до конца этой проблемой, приведу пример. В нем, преобразование, рекомендуемое разработчиками, приводит к «странному» поведению программы:

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

Здесь, поскольку параметр передаётся по значению, при вызове будет создана локальная копия переменной (указателя) Msg. Об этом я ещё расскажу ниже. Эта переменная, при завершении процедуры будет уничтожаться, что приведёт к освобождению «персональной» копии экземпляра переданной и преобразованной строки.

Функции этой группы используются для сравнения строк. Результатом будет одно из значений:

>0 если S1 > S2
255 символов приходится платить.

Если же тебе достаточно и 255 символов, то используй ShortString, или String[n].

Есть еще одно, на мой взгляд, замечание. Если Вы обратили внимание на тип переменной Len в моем примере, то возможно у Вас возник вопрос: А почему LongInt, а не Integer? Жаль если у Вас вопрос не возник – либо вы все знаете, либо ничего :). Для остальных поясню: дело в том, что тип LongInt фундаментальный тип, размер которого (4 байта) не будет меняться в последующих версиях Delphi. А тип Integer, это универсальный тип, размерность которого может меняться от версии к версии. Например, для 64-разрядных компьютеров он наверняка «вырастет» до 8-ми байт (64 бита). Лично мне, хочется, что бы файлы данных записанные моей старой версией программы могли быть нормально прочитаны более поздними версиями, возможно скомпилированными уже под 64-разрядной OS.

Использование строк в записях

Проблема возникает тогда, когда одно поле (или несколько полей) имеют тип динамической строки. В этом случае, часто возникает проблема схожая с проблемой записи динамической строки в файл – не все данные лежат в записи, динамические строки представлены в ней лишь указателями. Решается проблема также как и с записью строк в файл. Жаль только что тогда нельзя будет оперировать (записать/прочитать) целиком всей записью. Строки придется обрабатывать особо. Можно сделать, например, так:

Обратите внимание на то, что перед записью в поток я делаю так, что бы в поле f3 попал указатель Nil. Если этого не сделать, то в поток попадет адрес текущего экземпляра динамической строки. При чтении, он будет прочитан в поле f3. Т.е. поле f3 станет указывать на какое-то место в памяти. При выполнении SetLength, поскольку Delphi сочтет что текущее значение f3 лежит по указанному адресу, будет попытка интерпретировать лежащую там информацию как динамическую строку. Если же в поток записать Nil, то SetLength, никуда лезть не будет – экземпляра-то нет.

Использование строк в качестве параметров и результатов функций размещенных в DLL.

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

Общий смысл этого эпоса в том, что если Ваша Dll экспортирует хотя бы одну процедуру или функцию с типом параметра соответствующим любой динамической строке (AnsiString например), или функцию, возвращающую результат такого типа. Вы должны обязательно и в Dll, и в использующей ее программе, первым модулем в списке импорта (uses) указать модуль ShareMem. И как следствие, поставлять со своей программой и Dll еще одну стандартную библиотеку BORLNDMM.DLL.

Вы не задумывались над вопросами: «Зачем все эти сложности?»; «Что будет если этого не сделать?» и «Можно ли этого избежать?»; «Если да, то как?» Если не задумывались, то самое время сделать это.

Попробуем разобраться что будет происходить с экземплярами динамических строк в следующем примере:

Сначала, при выполнении процедуры X, функция IntToStr(100) создаст экземпляр динамической строки ‘100’, и ее адрес будет помещен в переменную Str. Затем, адрес этой переменной будет передан процедуре Y. В ней, при выполнении оператора s := s+’$’, будет создан экземпляр новый строки ‘100$’, Экземпляр старой строки ‘100’ станет не нужным и память, выделенная для него при создании, будет освобождена. Кроме того, при завершении процедуры X, будет освобождена и память, выделенная для строки ‘100$’, так как перестанет существовать единственная ссылка на нее — переменная Str.

Всё вроде бы хорошо. Но до тех пор, пока обе процедуры располагаются в одном исполняемом модуле (EXE-файле). Если например поместить процедуру Y в Dll, а процедуру X оставить в EXE, то будет беда.

Дело в том, что выделением и освобождением памяти для экземпляров динамических строк занимается внутренний менеджер памяти Delphi-приложения. Использовать стандартный менеджер Windows очень накладно. Он слишком универсален, и потому медленный, а строки очень часто требуют перераспределения памяти. Вот разработчики Delphi и создали свой. Он ведет списки распределенной и свободной памяти своего приложения. Так вот, вся беда в том, что Dll будет использоваться свой менеджер памяти, а EXE свой. Друг о друге они ничего не знают. Поэтому, попытка освобождения блока памяти выделенного не своим менеджером приведёт к серьезному нарушению в его работе. Причем, это нарушение может проявиться далеко не сразу, и довольно необычным образом.

В нашем случае, память под строку ‘100’ будет выделена менеджером EXE-файла, а освобождаться она будет менеджером DLL. То же произойдет и с памятью под строку ‘100$’, только наоборот.

Для преодоления этой проблемы, разработчики Delphi создали библиотеку BORLNDMM.DLL. Она включает в себя еще один менеджер памяти :). Использование же модуля ShareMem, приводит к тому, что он заменяет встроенный в EXE (DLL) менеджер памяти на менеджер расположенный в BORLNDMM.DLL. Т.е., теперь и EXE-файл и DLL, будут использовать один, общий менеджер памяти.

Здесь важно отметить то, что если какой-либо из программных модулей (EXE или DLL) не будут иметь в списке импорта модуля ShareMem, то вся работа пойдет насмарку. Опять будут работать несколько менеджеров памяти. Опять будет бардак.

Можно обойтись и без внешнего менеджера памяти (BORLNDMM.DLL). Но для этого, надо например заменить встроенный в DLL менеджер памяти, на менеджер, встроенный в EXE. Такое возможно. Есть даже соответствующая реализация от Emil M. Santos, называемая FastShareMem. Найти ее можно на сайте http://www.codexterity.com. Она тоже требует обязательного указания ее модуля FastShareMem в списках используемых модулей EXE и DLL. Но, она по крайней мере не требует таскать за собой ни каких дополнительных DLL’лек.

Ну вот, наконец-то и все. Теперь, Вы знаете о строках почти столько же как я :).

Конечно, этим тема не исчерпывается. Например, я ничего не рассказал о мультибайтовых строках (MBCS) используемых для мультиязыковых приложений. Может и еще что-то забыл рассказать. Но, не расстраивайтесь. Я свои знания получал, изучая книги, тексты своих и чужих программ, код сгенерированный компилятором, и т.п. Т.е., все из открытых источников. Значит это все доступно и Вам. Главное, чтобы Вы были любознательными, и почаще задавали себе вопросы «Как?», «Почему?», «Зачем?». Тогда во всем сможете разобраться и сами.

CompareStr — Функция Delphi

Оба позволяют указать используемый языковой стандарт. Является ли Windows более «полной» из-за доступных флагов сравнения? Следовательно, один быстрее другого?

CompareStr (», loInvariantLocale) — это просто побайтовое сравнение символов в строке. CompareStr (», loUserLocale) вызывает внутреннюю функцию CompareString, поэтому они идентичны, за исключением дополнительных флагов, которые может принимать CompareString. Он также встроен, поэтому вы не должны видеть никакой разницы в скорости между ним и непосредственным вызовом CompareString.

ASD-SOFT

Программирование. Теория и практика.

TStringHelper — помощник при работе с типом String в Delphi.

Здравствуйте уважаемые коллеги!
TStringHelper, как и помощники в общем, появились в Delphi начиная с версии XE3. Ниже приведено описание и примеры использования методов и свойств помощника TStringHelper.

Empty

Возвращает пустую строку.

Create(C: Char; Count: Integer)

Создает строку из символов C количеством Count;

Create(const Value: array of Char)

Создает строку из переданного массива символов Value.

Create(const Value: array of Char; StartIndex: Integer; Length: Integer)

Создает строку из массива символов Value начиная с позиции StartIndex количеством Length символов.

Compare(const StrA: string; const StrB: string)

Сравнение двух строк StrA и StrB с учетом регистра. Если StrA StrB, то возвращает положительное значение, если строки равны, то возвращает 0.

Compare(const StrA: string; const StrB: string; IgnoreCase: Boolean)

Сравнение двух строк StrA и StrB с учетом, IgnoreCase установле в False, или без учета регистра, IgnoreCase установлен в True. Если StrA StrB, то возвращает положительное значение, если строки равны, то возвращает 0.

Compare(const StrA: string; IndexA: Integer; const StrB: string; IndexB: Integer; Length: Integer)

Сравнить строку StrA, начиная с символа IndexA со строкой StrB, начиная с символа IndexB в количестве Length символов с учетом регистра. Если StrA StrB, то возвращает положительное значение, если строки равны, то возвращает 0.

Compare(const StrA: string; IndexA: Integer; const StrB: string; IndexB: Integer; Length: Integer; IgnoreCase: Boolean)

Сравнить строку StrA, начиная с символа IndexA со строкой StrB, начиная с символа IndexB в количестве Length символов. С учетом, IgnoreCase устанавливается в False, или без учета регистра, IgnoreCase устанавливается в True. Если StrA StrB, то возвращает положительное значение, если строки равны, то возвращает 0.

CompareOrdinal(const strA: string; const strB: string)

Сравнивает строку StrA со строкой StrB по кодам символов.

CompareOrdinal(const strA: string; indexA: Integer; const strB: string; indexB: Integer; length: Integer)

Сравнивает по кодам символов строку StrA, начиная с символа IndexA со строкой StrB, начиная с символа IndexB в количестве Length символов.

CompareTo(const strB: string)

Сравнивает текущую строку со строкой StrB. Если Текущая строка StrB, то возвращает положительное значение, если строки равны, то возвращает 0.

Contains(const Value: string)

Если текущая строка содержит строку Value, то вернет True иначе False. Учитывается регистр.

Copy(const Str: string)

Возвращает строку Str.

CopyTo(SourceIndex: Integer; var destination: array of Char; DestinationIndex: Integer; Count: Integer)

Копирует текущую строку, начиная с символа SourceIndex в массив символов destination, начиная с DestinationIndex в количестве Count символов.

EndsText(const ASubText, AText: string)

Сравнивает окончание строки AText со строкой ASubText. При совпадении возвращает True.

EndsWith(const Value: string)

Сравнивает окончание текущей строки со строкой Value с учетом регистра. При совпадении возвращает True.

EndsWith(const Value: string; IgnoreCase: Boolean)

Сравнивает окончание текущей строки со строкой Value. IgnoreCase = True — без учета регистра, IgnoreCase = False — с учетом регистра. При совпадении возвращает True.

Equals(const Value: string)

Сравнивает текущую строку со строкой Value с учетом регистра. При совпадении возвращает True.

Equals(const a: string; const b: string)

Сравнивает строку a со строкой b с учетом регистра. При совпадении возвращает True.

Format(const Format: string; const args: array of const)

Подставляет значения в форматированную строку Format из массива args.

GetHashCode

В данный момент не работает. Возвращает -1.

IndexOf(value: Char)

Возвращает позицию символа value в текущей строке. Если символ не найден, вернет -1;

IndexOf(const Value: string)

Возвращает позицию совпадения строки Value с текущей строкой. Если строка не найдена, вернет -1.

IndexOf(Value: Char; StartIndex: Integer)

Возвращает позицию символа value в текущей строке, начиная с позиции StartIndex. Если символ не найден, вернет -1;

IndexOf(const Value: string; StartIndex: Integer)

Возвращает позицию совпадения строки Value с текущей строкой, начиная с позиции StartIndex. Если строка не найдена, вернет -1.

IndexOf(Value: Char; StartIndex: Integer; Count: Integer)

Возвращает позицию символа value в текущей строке, начиная с позиции StartIndex. Сравнивает Count сиволов. Если символ не найден, вернет -1.

IndexOf(const Value: string; StartIndex: Integer; Count: Integer)

Возвращает позицию совпадения строки Value с текущей строкой, начиная с позиции StartIndex, включая Count символов. Если строка не найдена, вернет -1.

IndexOfAny(const AnyOf: array of Char)

Возвращает позицию совпадения любого из массива AnyOf в текущей строке. Если ни один символ не найден, то вернет -1.

IndexOfAny(const AnyOf: array of Char; StartIndex: Integer)

Возвращает позицию совпадения любого из массива AnyOf в текущей строке, начиная с позиции StartIndex. Если ни один символ не найден, то вернет -1.

IndexOfAny(const AnyOf: array of Char; StartIndex: Integer; Count: Integer)

Возвращает позицию совпадения любого символа из массива AnyOf в текущей строке, начиная с позиции StartIndex, проверяя Count символов. Если ни один символ не найден, то вернет -1.

Insert(StartIndex: Integer; const Value: string)

Вставляет строку Value в текущую строку начиная с позиции StartIndex.

IsDelimiter(const Delimiters: string; Index: Integer)

Проверяет: присутствует ли текущая строка в строке Delimiters начиная с позиции Index.

IsEmpty

Возвращает True, если Текущая строка пустая.

IsNullOrEmpty(const Value: string)

Возвращает True, если строка Value пустая.

IsNullOrWhiteSpace(const Value: string)

Не работает. Возвращает False.

Join(const Separator: string; const values: array of const)

Не работает. Возвращает пустую строку.

Join(const Separator: string; const Values: array of string)

Объединяет значения из массива Values в строку используя разделитель Separator.

Join(const Separator: string; const Values: IEnumerable )

Не работает. Возвращает пустую строку.

Join(const Separator: string; const value: array of string; StartIndex: Integer; Count: Integer)

Объединяет значения из массива Values, начиная с позиции StartIndex количеством Count в строку используя разделитель Separator.

LastDelimiter(const Delims: string)

Возвращает последнюю совпавшую позицию строки Delims с текущей строкой. Если совпадений не найдено, то вернет -1.

LastIndexOf(Value: Char)

Возвращает последнюю позицию символа Value в текущей строке. Если совпадений не найдено, то вернет -1.

LastIndexOf(const Value: string)

Возвращает последнюю позицию совпадения строки Value с текущей строкой. Если строка не найдена, вернет -1.

LastIndexOf(Value: Char; StartIndex: Integer)

Возвращает последнюю позицию символа Value в текущей строке, сравнивает с начала и до позиции StartIndex. Если совпадений не найдено, то вернет -1.

LastIndexOf(const Value: string; StartIndex: Integer)

Возвращает последнюю позицию совпадения строки Value в текущей строке, сравнивает с начала и до позиции StartIndex. Если строка не найдена, вернет -1.

LastIndexOf(Value: Char; StartIndex: Integer; Count: Integer)

Возвращает последнюю позицию символа Value в текущей строке, сравнивает с начала и до позиции StartIndex, проверяя Count символов. Если совпадений не найдено, то вернет -1.

LastIndexOf(const Value: string; StartIndex: Integer; Count: Integer)

Возвращает последнюю позицию строки Value в текущей строке, сравнивает с начала и до позиции StartIndex, проверяя Count символов. Если совпадений не найдено, то вернет -1.

LastIndexOfAny(const AnyOf: array of Char)

Возвращает последнюю позицию любого найденного символа из массива AnyOf в текущей строке. Если совпадений не найдено, то вернет -1.

LastIndexOfAny(const AnyOf: array of Char; StartIndex: Integer)

Возвращает последнюю позицию любого найденного символа из массива AnyOf в текущей строке до позиции StartIndex. Если совпадений не найдено, то вернет -1.

LastIndexOfAny(const AnyOf: array of Char; StartIndex: Integer; Count: Integer)

Возвращает последнюю позицию любого найденного символа из массива AnyOf, начиная с позиции StartIndex, проверяя Count символов. Если совпадений не найдено, то вернет -1.

PadLeft(TotalW >Дополняет текущую строку пробелами до длинны TotalWidth слева.
PadLeft(TotalW >Дополняет текущую строку символами PaddingChar до длинны TotalWidth слева.
PadRight(TotalW >Дополняет текущую строку пробелами до длинны TotalWidth справа.
PadRight(TotalW >Дополняет текущую строку символами PaddingChar до длинны TotalWidth справа.
Remove(StartIndex: Integer)

Удаляет символы из текущей строки начиная с позиции StartIndex и до конца.

Remove(StartIndex: Integer; Count: Integer)

Удаляет Count символов из текущей строки начиная с позиции StartIndex.

Replace(OldChar: Char; NewChar: Char)

Заменяет все символы OldChar в текущей строке на симвопл NewChar.

Replace(OldChar: Char; NewChar: Char; ReplaceFlags: TReplaceFlags)

Заменяет символы OldChar в текущей строке на симвопл NewChar, используя насройки ReplaceFlags: rfReplaceAll — заменить все найденные; rfIgnoreCase — игнорировать регистр.

Replace(const OldValue: string; const NewValue: string)

Заменяет все совпадения со строкой OldValue в текущей строке на строку NewValue.

Replace(const OldValue: string; const NewValue: string; ReplaceFlags: TReplaceFlags)

Заменяет все совпадения со строкой OldValue в текущей строке на строку NewValue, используя насройки ReplaceFlags: rfReplaceAll — заменить все найденные; rfIgnoreCase — игнорировать регистр.

Split(const Separator: array of Char)

Разделяет текущую строку на массив строк TArray используя в качетсве разделителей символы из массива Separator.

Split(const Separator: array of Char; Count: Integer)

Разделяет текущую строку на массив строк TArray количеством Count, используя в качетсве разделителей символы из массива Separator.

Split(const Separator: array of Char; Options: TStringSplitOptions)

Разделяет текущую строку на массив строк TArray используя в качетсве разделителей символы из массива Separator. Options — условия разделения: None и ExcludeEmpty — исключать пустые.

Split(const Separator: array of string; Options: TStringSplitOptions)

Разделяет текущую строку на массив строк TArray используя в качетсве разделителей строки из массива Separator. Options — условия разделения: None и ExcludeEmpty — исключать пустые.

Split(const Separator: array of Char; Count: Integer; Options: TStringSplitOptions)

Разделяет текущую строку на массив строк TArray количеством Count, используя в качетсве разделителей символы из массива Separator. Options — условия разделения: None и ExcludeEmpty — исключать пустые.

Split(const Separator: array of string; Count: Integer; Options: TStringSplitOptions)

Разделяет текущую строку на массив строк TArray используя в качетсве разделителей строки из массива Separator. Options — условия разделения: None и ExcludeEmpty — исключать пустые.

StartsWith(const Value: string)

Сравнивает начало текущей строки со строкой Value. Возвращает True при совпадении.

StartsWith(const Value: string; IgnoreCase: Boolean)

Сравнивает начало текущей строки со строкой Value. С учетом регистра при IgnoreCase = False, и без учета при IgnoreCase = True. Возвращает True при совпадении.

Substring(StartIndex: Integer)

Возвращает часть текущей строки начиная с позиции StartIndex и до конца.

Substring(StartIndex: Integer; Length: Integer)

Возвращает часть текущей строки начиная с позиции StartIndex, количеством Length символов.

ToCharArray

Преобразует текущую строку в массив символов TArray .

ToCharArray(StartIndex: Integer; Length: Integer)

Преобразует текущую строку, начиная с позиции StartIndex, количеством Length в массив символов TArray .

ToLower

Переводит все символы текущей строки в нижний регистр.

ToLowerInvariant

Переводит все символы текущей строки в нижний регистр используя UTF-16.

ToUpper

Переводит все символы текущей строки в верхний регистр.

ToUpperInvariant

Переводит все символы текущей строки в верхний регистр используя UTF-16.

Trim

Удаляет пробелы из начала и конца текущей строки.

Trim(const TrimChars: array of Char)

Удаляет символы, указанные в массиве TrimChars из начала и конца текущей строки.

TrimEnd(const TrimChars: array of Char)

Удаляет символы, указанные в массиве TrimChars из конца текущей строки.

TrimStart(const TrimChars: array of Char)

Удаляет символы, указанные в массиве TrimChars из начала текущей строки.

Chars[Index: Integer]

Свойство вернет символ с позицией Index из текущей строки.

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL