我的c++代码使用boost来转换编码。
如果我在 cygwin 上编译和运行代码,它工作正常,但如果我直接在 Windows 命令行 (cmd) 上使用 mingw-w64 或 msvc11 编译代码,以下代码会抛出 invalid_charset_error。
boost::locale::conv::between( encheckbeg, encheckend, consoleEncoding,
getCodingName(codingMethod) )
encheckbeg 和 encheckend 是指向 char 的指针。 consoleEncoding 是一个 c 字符串,可以是“Big5”或“UTF-8”。 getCodingName 返回c-string,内容为字符集名称。
当 getCodingName 返回“UTF-16LE”“UTF-16BE”时,出现异常。其他 chaset 名称如“Big5”“GB18030”“UTF-8”,我已经测试过这些名称,boost::locale::conv::between 可以识别它们。所以我认为问题出在 UTF-16 上。
是不是boost的charset转换依赖于OS locale机制,所以才会出现上面的问题?为什么不使用 ICU 转换为 UTF-16?我该如何解决这个问题?
最佳答案
Boost Locale 不是一个只有头文件的库。有3种实现方式:
- ICU:使用 ICU4C 库
- iconv:使用iconv库
- wconv:使用 Windows API
当您使用 MSVC 构建 Boost Locale 时,wconv 是默认选择。
不幸的是,Windows API,例如 MultiByteToWideChar ,用于执行转换的不支持UTF-16(您可以看一下API描述。我认为原因是wchar_t(LPWSTR)
已经是UTF-16 ...)
一个可能的解决方案是为 UTF-16 添加额外的代码,例如:
std::string mbcs = std::string("...");
std::wstring wstr = boost::locale::conv::to_utf<wchar_t>(mbcs,"Big5");//for Big5/GBK...
//wstr = boost::locale::conv::utf_to_utf<wchar_t>(utf8str);//for UTF-8
std::wstring_convert<std::codecvt_utf16<wchar_t>> utf16conv;//for UTF-16BE
//std::wstring_convert<std::codecvt_utf16<wchar_t, 0x10ffff, little_endian>> utf16conv;//for UTF-16LE
std::string utf16str = utf16conv.to_bytes(wstr);
当然,您也可以使用 ICU 构建 Boost Locale。请记住首先构建它并随您的程序一起交付所需的运行时库/文件。
关于c++ - 为什么我不能在 Windows 上使用 boost::locale::conv::between 将 UTF-16 文本转换为其他编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28895652/