5

我正在尝试将 UTF-16 编码的字符串转换为 UCS-4

如果我理解正确,C++11 通过 codecvt_utf16 提供了这种转换。

我的代码是这样的:

#include <iostream>
#include <locale>
#include <memory>
#include <codecvt>
#include <string>

using namespace std;

int main()
{
    u16string s;

    s.push_back('h');
    s.push_back('e');
    s.push_back('l');
    s.push_back('l');
    s.push_back('o');

    wstring_convert<codecvt_utf16<wchar_t>, wchar_t> conv;
    wstring ws = conv.from_bytes(reinterpret_cast<const char*> (s.c_str()));

    wcout << ws << endl;

    return 0;
}

注意:明确的 push_backs 可以绕过我的 clang 版本(Xcode 4.2)没有 unicode 字符串文字这一事实。

当代码运行时,我得到终止异常。我在这里做违法的事吗?我在想它应该可以工作,因为我传递给 wstring_convert 的 const char* 是 UTF-16 编码的,对吧?我也认为字节顺序是问题,但我检查过它不是这种情况。

4

1 回答 1

10

两个错误:

1)from_bytes()采用单字节的重载需要const char*一个以空字符结尾的字节字符串,但你的第二个字节是'\0'。

2)您的系统可能是小端,因此您需要从 UTF-16LE 转换为 UCS-4:

#include <iostream>
#include <locale>
#include <memory>
#include <codecvt>
#include <string>

using namespace std;

int main()
{
    u16string s;

    s.push_back('h');
    s.push_back('e');
    s.push_back('l');
    s.push_back('l');
    s.push_back('o');

    wstring_convert<codecvt_utf16<wchar_t, 0x10ffff, little_endian>,
                     wchar_t> conv;
    wstring ws = conv.from_bytes(
                     reinterpret_cast<const char*> (&s[0]),
                     reinterpret_cast<const char*> (&s[0] + s.size()));

    wcout << ws << endl;

    return 0;
}

在 Windows 上使用 Visual Studio 2010 SP1 和在 Linux 上使用 CLang++/libc++-svn 进行测试。

于 2011-12-16T22:05:50.327 回答