StrLComp против AnsiStrLComp при вызове со строками Unicode - PullRequest
4 голосов
/ 29 февраля 2012

У меня немного путаница в отношении функций "Ansi" против "обычных" строк RTL при вызове со строками Unicode.Я понимаю, что в более старых версиях Delphi (когда Ansistring был по умолчанию) версии «Ansi» обрабатывали многобайтовые символы.Означает ли это что-нибудь при работе со строками Unicode?Предполагая, что мне нужно обрабатывать корейские символы, а также что мой код не должен быть совместим со старыми версиями Delphi, какие функции rtl следует использовать?

Ответы [ 3 ]

7 голосов
/ 01 марта 2012

Префикс «Ansi» функций сравнения строк действительно никогда не означал ничего, кроме того, что языковой стандарт учитывался при сравнении строк вместо «простого» простого двоичного сравнения. В мире Unicode это все еще так. Семейство функций Ansi * также принимает (Unicode) строки в качестве своих параметров и учитывает локаль при выполнении сравнения.

Из документа AnsiCompareStr (D2009):

Большинство языков считают строчные буквы меньше, чем соответствующие заглавные буквы. Это в отличие от ASCII порядок, в котором строчные символы больше прописных персонажи. Таким образом, установка S1 в «a» и S2 в «A» вызывает AnsiCompareStr для возврата значения меньше нуля, тогда как CompareStr, с теми же аргументами возвращает значение больше нуля.

То, что эффект "принятия во внимание локали" может отличаться в зависимости от локали. Это может иметь отношение к символам с акцентом или нет. В версиях Юникода это может фактически учитывать то, как составлены символы. Например, акцентированный e (é) может быть закодирован точно так же, но также может быть закодирован как два отдельных элемента: ударение и e.

Функции Ansi * и "обычные" сравнения строк включены в модуль SysUtils. Все они принимают строки в качестве своих параметров, и в Unicode Delphi это действительно означает UnicodeStrings.

Если вам нужно работать с AnsiStrings, вам нужно использовать модуль AnsiStrings. Он имеет тот же набор функций сравнения строк, но в этом модуле все они принимают AnsiStrings в качестве своих параметров.

Теперь, если вам не нужна совместимость со старыми версиями: используйте стандартные функции из SysUtils. Используйте нормальные, если байтового сравнения достаточно. Используйте анси, если вам необходимо принять во внимание региональные соображения.

4 голосов
/ 01 марта 2012

Не уверен, что именно вы хотите сделать, но ...

  • , если вы хотите сравнить две строки по вашим текущим пользовательским языковым правилам, используйте AnsiStrLComp для сравнения с учетом регистра или AnsiStrLIComp для сравнения без учета регистра.Внутренне эти функции используют функцию CompareString с набором языковых настроек LOCALE_USER_DEFAULT

  • , если вы хотите сравнить две строки с помощьюВнутренний механизм сравнения Delphi, используйте функцию StrLComp для сравнения с учетом регистра или StrLIComp для сравнения без учета регистра

Так что если выЕсли вы сравните две одинаковые строки с AnsiStrLComp или AnsiStrLIComp на машинах с различными настройками языкового стандарта пользователя, вы можете получить разные результаты, но с другой стороны вы можете получить естественныйсортировка по языковым настройкам пользователя в вашем приложении.StrLComp и StrLIComp будут работать на всех машинах одинаково, независимо от локали.

2 голосов
/ 01 марта 2012

Простой ответ заключается в том, что когда дело касается строковых подпрограмм Delphi, вы должны использовать функции ANSI ... () для строк Unicode.

Однако, если вы сравнивая строк (помимо прочего), вам также может понадобиться сначала нормализовать эти строки, в зависимости от характера и потребностей (и источника строк) в вашем приложении, чтобы иметь дело с эквивалентностью Unicode .

...