c ++ towupper()不转换某些字符

时间:2017-01-08 22:47:22

标签: c++ c++builder unicode-string

我使用Borland C ++ Builder 2009,我的应用程序被翻译成多种语言,包括波兰语。

对于一小部分功能,我使用towuppper()来大写字符串,在用户首次忽略时强调它。

原始字符串从语言dll加载到utf16 wstring对象中,我这样转换:

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

所有这一切都运作良好,除了波兰语,其中一句话:“Rozumiemryzykownośćwykonaniatej operacji”转换为“ROZUMIEM RYZYKOWNO ść WYKONANIA TEJ OPERACJI”而不是“ROZUMIEM RYZYKOWNO ŚĆ< / strong> WYKONANIA TEJ OPERACJI“

(注意“ryzykowność”这两个字的最后两个字符不会转换。)

这并不是说这个角色没有大写的Unicode变体。 Unicode字符346可以解决问题。 http://www.fileformat.info/info/unicode/char/015a/index.htm

这是我过时的编译器安装中过时库的问题还是我错过了其他内容?

2 个答案:

答案 0 :(得分:11)

C ++标准不要求towupper的实现来执行Unicode大小写转换。即使宽字符串是Unicode字符串。即使在一个小写代码点与一个大写的代码点匹配的情况下也是如此。

此外,即使实现支持,towupper也无法执行正确的Unicode大小写转换。大小写转换实际上可以更改Unicode字符序列中的代码点数。 towupper无法做到这一点。

不能依赖C ++标准库来处理这类Unicode问题。您需要转移到ICU这样的专用Unicode库。

答案 1 :(得分:2)

在Windows上,这将有效: 编辑刚刚意识到你正在使用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:
}

首先,您需要将区域设置设置为&#39; polish&#39;使用setlocale。然后使用_towupper_l。 这是一个link,可以告诉您setlocale可以使用哪些字符串(引用特定语言)。

编辑: 请注意,如果我打印结果:

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

输出将是:

c1 = S, c2 = C

但是如果我在调试器中观察C1和C2的值,我可以看到正确的结果,带有重音符号。我的控制台不会打印那种字符。