2012-01-10 6 views
1

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

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

Как LCID - это тип Windows, есть ли функция Windows, которая будет конвертировать широкие строки в верхний или нижний регистр?

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

+0

Не можете использовать '' towupper' или towlower'? –

+0

Нет. Прошу прощения, я забыл добавить комментарий об этом в мой первоначальный пост. В документе doc для towupper() говорится: «Преобразование случая буксировки является специфичным для локали. В этом случае изменяются только символы, относящиеся к текущему языку. Функции без суффикса _l используют установленный в настоящий момент язык. Версии этих функций с _l принимают локаль в качестве параметра и используют это вместо текущего установленного языкового стандарта ».LCID может не соответствовать текущему языку, поэтому вам нужно использовать версию _l и передать применимый _locale_t, чтобы получить надежный результат с использованием этой локали. – appleton

ответ

0

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

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

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

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

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

Что забывает упомянуть залит пару постов на замечательный блог Майкла Каплана по вопросам интернационализации: What does "linguistic casing" mean?, How best to alter case. Исполнительное резюме является то, что вы достичь тех же результатов, что и CharXxx семейства функций, вызвав LCMapString и не указав LCMAP_LINGUISTIC_CASING флаг, в то время как вы можете быть лингвистически чувствительным, гарантируя, что вы сделать указать 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. 
}