WideCharToMultiByte问题

时间:2010-07-30 14:25:32

标签: c++ unicode utf-8 utf-16 widechar

我拥有previous question中可爱的功能,如果我这样做可以正常工作:

wstring temp;
wcin >> temp;

string whatever( toUTF8(getSomeWString()) );

// store whatever, copy, but do not use it as UTF8 (see below)

wcout << toUTF16(whatever) << endl;

原始表单被复制,但是表单之间通常包含额外的字符。如果我输入例如àçé作为输入,并添加cout << whatever语句,我将获得┬à┬ç┬é作为输出。

我是否仍然可以使用此字符串与其他人进行比较,从ASCII源获取?或者换一种说法:如果我通过linux中的UTF8 cout输出┬à┬ç┬é,它会读取àçé吗?字符串àçé的字节内容是否由cin读取为UTF8 linux,与Win32 API对我的描述完全相同?

谢谢!

PS:我问的原因是因为我需要使用很多字符串来比较其他读取值(比较和连接......)。

2 个答案:

答案 0 :(得分:5)

让我们从我开始说,似乎只有没有方式通过cout将UTF-8文本输出到Windows中的控制台(假设您使用Visual Studio进行编译)。 但是,对于测试,您可以通过Win32 API fn WriteConsoleA输出您的UTF-8文本:

if(!SetConsoleOutputCP(CP_UTF8)) { // 65001
    cerr << "Failed to set console output mode!\n";
    return 1;
}
HANDLE const consout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD nNumberOfCharsWritten;
const char* utf8 = "Umlaut AE = \xC3\x84 / ue = \xC3\xBC \n";
if(!WriteConsoleA(consout, utf8, strlen(utf8), &nNumberOfCharsWritten, NULL)) {
    DWORD const err = GetLastError();
    cerr << "WriteConsole failed with << " << err << "!\n";
    return 1;
}

这应输出: 如果您将控制台(cmd.exe)设置为使用Lucida控制台字体,则为Umlaut AE = Ä / ue = ü

关于你的问题(取自你的评论),如果

  

win23 API转换后的字符串是   与原始UTF8(linux)字符串相同

我会说是:给定Unicode字符序列,通过WideCharToMultiByte函数转换为UTF-8(char)表示的UTF-16(Windows wchar_t)表示将始终产生相同的字节序列。 / p>

答案 1 :(得分:1)

当您将字符串转换为UTF 16时,它是一个16字节宽的字符,您无法将其与ASCII值进行比较,因为它们不是16字节值。您必须将它们转换为比较,或者将专门的比较写入ASCII函数。

我怀疑linux中的UTF8 cout会产生相同的正确输出,除非它是常规的ASCII值,如UTF8 UTF-8 encoding forms are binary-compatible with ASCII for code points below 128, 并且我假设UTF16以UTF8的方式出现在simliar中。

好消息是,有很多converters用于将这些字符串转换为不同的字符集。