преобразовать регистр широких символов, учитывая LCID (Visual C ++) - PullRequest
1 голос
/ 10 января 2012

У меня есть некоторый существующий код Visual C ++, где мне нужно добавить преобразование строк широких символов в верхний или нижний регистр.

Я знаю, что в этом есть подводные камни (например, турецкое "I"),но большинство из них можно сгладить, если вы знаете язык.К счастью, в этой области кода я знаю значение LCID (ID локали), которое, как мне кажется, совпадает со знанием языка.

Поскольку LCID является типом Windows, существует ли функция Windows, которая преобразует широкие строки вверхний или нижний регистр?

Функция времени выполнения C _towupper_l () звучит так, как будто она идеальна, но вместо LCID принимает параметр _locale_t, поэтому я думаю, что он не подходит, если не существует полностью надежного способа преобразования LCIDна _locale_t.

1 Ответ

0 голосов
/ 07 февраля 2013

Функция, которую вы ищете, называется LCMapString и является частью API Windows NLS.Флаг LCMAP_UPPERCASE отображает символы в верхний регистр, в то время как LCMAP_LOWERCASE отображает символы в нижний регистр.

Для приложений, ориентированных на Windows Vista и более поздние версии, существует вариант Ex , который работает наИмена локалей вместо идентификаторов, которые, по словам Microsoft, вы должны использовать.

На самом деле, в реализации CRT, предоставляемой VS 2010 (и, предположительно, других версиях), такие функции, как _towupper_lв конце концов, в итоге вы получите LCMapString после того, как они извлекут ID локали (LCID) из указанного _locale_t.

Если вы похожи на меня и менее знакомы с API i8n, чем должны быть, вы, вероятно,уже известно о семействе функций CharUpper, CharLower, CharUpperBuff и CharLowerBuff.Это были старые резервные системы с первых дней Windows для изменения регистра символов / строк, но, как предупреждает их документация:

Обратите внимание, что CharXxx всегда отображает прописные буквы I в строчные I ("я "), даже если текущий язык турецкий или азербайджанский.Если вам нужна функция, которая в этом отношении чувствительна к лингвистике, позвоните LCMapString.

То, что она не упомянула, заполнено парой постов о чудесном Майкла Каплана.блог по вопросам интернационализации: Что означает «лингвистический регистр»? , Как лучше всего изменить регистр .Суть в том, что вы достигаете тех же результатов, что и семейство функций CharXxx, вызывая LCMapString и , а не , указывая флаг LCMAP_LINGUISTIC_CASING, тогда как вы можете быть чувствительными к лингвистике, гарантируя, что вы do укажите флаг LCMAP_LINGUISTIC_CASING.

Пример кода:

std::wstring test("Does my code pass the Turkey test?");
if (!LCMapStringW(lcid,            /* your LCID, defined elsewhere */
                  LCMAP_UPPERCASE | LCMAP_LINGUISTIC_CASING,
                  test.c_str(),    /* input string */
                  test.length(),   /* length of input string */
                  &test[0],        /* output buffer (can reuse input) */
                  test.length()))  /* length of output buffer (same as input) */
{
   // Uh-oh! Something went wrong in the call to LCMapString, so you need to
   // handle the error somehow here.
   // A good start is calling GetLastError to determine the error code.
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...