2017-01-08 9 views
6

Я использую Borland C++ Builder 2009, и мое приложение переведено на несколько языков, включая польский.C++ towupper() не конвертирует определенные символы

Для небольшой части функциональности я использую towuppper(), чтобы использовать строку, чтобы подчеркнуть ее при первом игнорировании пользователем.

Исходная строка загружается из библиотеки DLL языка, в объект utf16 wstring и преобразовать так:

int length = mystring.length() ; 
for (int x = 0 ; x < length ; x++) 
    { 
    mystring[x] = towupper(mystring[x]); 
    } 

Все это работает хорошо, для Польши, где следующее предложение, кроме: «Rozumiem ryzykowność wykonania тедж operacji»превращается в "ROZUMIEM RYZYKOWNO СБН WYKONANIA TEJ oPERACJI" вместо "ROZUMIEM RYZYKOWNO СБН WYKONANIA TEJ oPERACJI"

(уведомление о том, что два последних символов слова "ryzykowność" не конвертировать).

Это не так, как если бы у этого символа не было никаких заглавных вариантов Юникода. Символ Юникода 346 делает трюк. http://www.fileformat.info/info/unicode/char/015a/index.htm

Является ли это устаревшей библиотекой в ​​устаревшей установке компилятора или мне не хватает чего-то еще?

+0

Являются ли эти символы нормализованными или состоят из нескольких комбинированных блоков кода? – user2079303

+0

Это не должно быть устаревшей библиотекой, так как «ś» и «Ś» присутствовали в Unicode v.1.1 от 1993 года.Если это так, это ошибка создателя этой функции. – usr2564301

+0

Какова ваша локаль языка C? «Верхняя версия ch или unmodified ch, если ни одна версия в верхнем регистре не указана в текущей языковой версии C». Вы находитесь в юникодном локали? 'std :: setlocale (LC_ALL," en_US.utf8 ");'? Из http://en.cppreference.com/w/cpp/string/wide/towupper можно легко прочитать документы о функции, найденной через google. Если это не решит проблему, предоставьте [mcve] – Yakk

ответ

11

Реализации towupper не требуются стандартом C++ для выполнения конверсий в формате Unicode. Даже если широкие строки являются строками Unicode. Даже в тех случаях, когда один нижний регистр кодов совпадает с одним верхним регистром.

Кроме того, towupper не может выполнить правильное преобразование кода в Юникоде, даже если реализация поддерживает его. Преобразование случая может фактически изменить количество кодовых точек в последовательности символов Юникода. И towupper не может этого сделать.

не может полагаться на стандартную библиотеку C++ для решения таких вопросов Юникода. Вам нужно будет перейти в специальную библиотеку Unicode, такую ​​как ICU.

+0

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

+1

@ M.M: Даже если реализация обеспечивает широкие функции символов, которые пытаются реализовать Unicode как можно больше, это все еще обещание, которое невозможно сохранить. Ненадежные функции * ненадежны *. Если вам нужен Unicode для работы, то вам нужно, чтобы он действительно работал *, а не в основном работать, за исключением тех случаев, когда это не так. –

+1

@NicolBolas все зависит от проблемной области. Если вы знаете, что будете работать с ограниченным подмножеством всех возможных языков, было бы полезно узнать, будет или нет простой подход к этим конкретным языкам. –

2

В Windows это будет работать: EDIT Только что понял, что вы используете Borland, а не Msvc.

#include <cctype> 
#include <clocale> 

int main(int argc, char** argv) 
{ 
    setlocale(LC_ALL, "polish"); 

    wchar_t c[2] = { L'ś', L'ć'}; 
    wchar_t c1 = _towupper_l(c[0], _get_current_locale()); 
    wchar_t c2 = _towupper_l(c[1], _get_current_locale()); 

    return 0: 
} 

Сначала необходимо установить локаль «полируют» с помощью setlocale. Затем используйте _towupper_l. Вот link, который сообщает вам, какие строки, ссылаясь на определенный язык, можно использовать с setlocale.

EDIT: Обратите внимание, что, если я распечатать результаты:

_wprintf_l(L" c1 = %c, c2 = %c\n", _get_current_locale(), c1, c2); 

Выход будет:

c1 = S, c2 = C 

Но если я смотрю значения C1 и C2 в моем отладчик, я могу см. правильные результаты, с акцентами. Моя консоль просто не печатает такие символы.

+0

Я не обязательно знаю локаль каждого предложения, которое может быть передано подпрограмме, и это может быть даже несколько языков в одном предложении. Он также поражает использование Unicode для начала. – Peter

+1

@Peter Что вы должны понимать, так это то, что, например, на французском языке, верхний регистр 'é' -' E', а не 'É'. Но для других языков, использующих букву 'é', верхний регистр' é' - 'É', а не' E'. Поэтому я не знаю, возможно ли то, что вы просите, потому что в верхнем регистре одна буква очень специфична для языка. EDIT: В моем сообщении есть ссылка о том, какие строки можно передать в 'setlocale'. – nikau6

+0

Я вижу вашу точку зрения. Благодарю.Я думаю, что идеальным решением будет попросить моих переводчиков предоставить две строки. Строчная строка и строчная строка – Peter

 Смежные вопросы

  • Нет связанных вопросов^_^