【问题标题】:WideCharToMultiByte problemWideCharToMultiByte 问题
【发布时间】:2011-03-23 07:00:43
【问题描述】:

我的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 &lt;&lt; whatever 语句,我将得到┬à┬ç┬é 作为输出。

我还可以使用这个字符串与其他字符串进行比较吗,从 ASCII 源获取?或者换个方式问:如果我通过 linux 中的 UTF8 cout 输出┬à┬ç┬é,它会读成àçé吗?字符串àçé的字节内容,在UTF8 linux中由cin读取,和Win32 API得到的完全一样吗?

谢谢!

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

【问题讨论】:

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


    【解决方案1】:

    首先让我说似乎没有没有方法可以通过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;
    }
    

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

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

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

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

    【讨论】:

    • 如果你反正用WriteConsole,也可以直接用WriteConsoleW写UTF-16字符串,省去SetConsoleOutputCP的必要。
    • @Philipp - 是的,首先从 utf16 转换为 utf8,然后使用 WriteConsoleA 没有什么意义。如果(测试)应用程序中的字符串已经是 utf8,它可能仍然有意义。
    【解决方案2】:

    当您将字符串转换为 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 之后。

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

    【讨论】:

    • 我知道转换(我在我链接到的上一个问题中使用它们,并且我正在转换正是因为我需要执行比较),并且我正在尝试确定 win23 API 是否转换string 与原始 UTF8 (linux) 字符串相同。 linux 上的cout 可以很好地输出字符,这就是它首先使用 UTF8 的原因(嗯,可能还有很多其他原因)。问题是,我不知道 ┬à┬ç┬é 字符串是否也存在于原始 UTF8 字符串中。
    猜你喜欢
    • 2011-08-25
    • 2014-05-25
    • 2011-08-03
    • 1970-01-01
    • 2011-06-10
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    相关资源
    最近更新 更多