C++ & Boost:编码/解码 UTF-8
Posted
技术标签:
【中文标题】C++ & Boost:编码/解码 UTF-8【英文标题】:C++ & Boost: encode/decode UTF-8 【发布时间】:2011-09-02 16:05:45 【问题描述】:我正在尝试做一个非常简单的任务:获取 unicode-aware wstring
并将其转换为 string
,编码为 UTF8 字节,然后相反:获取包含 UTF8 的 string
字节并将其转换为支持 unicode 的wstring
。
问题是,我需要它跨平台,我需要它与 Boost 一起工作......我似乎无法找到让它工作的方法。我一直在玩弄
http://www.edobashira.com/2010/03/using-boost-code-facet-for-reading-utf8.html 和 http://www.boost.org/doc/libs/1_46_0/libs/serialization/doc/codecvt.html尝试将代码转换为使用 stringstream
/wstringstream
而不是任何文件,但似乎没有任何效果。
例如,在 Python 中它看起来像这样:
>>> u"שלום"
u'\u05e9\u05dc\u05d5\u05dd'
>>> u"שלום".encode("utf8")
'\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d'
>>> '\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d'.decode("utf8")
u'\u05e9\u05dc\u05d5\u05dd'
我最终想要的是:
wchar_t uchars[] = 0x5e9, 0x5dc, 0x5d5, 0x5dd, 0;
wstring ws(uchars);
string s = encode_utf8(ws);
// s now holds "\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d"
wstring ws2 = decode_utf8(s);
// ws2 now holds 0x5e9, 0x5dc, 0x5d5, 0x5dd
我真的不想再增加对 ICU 的依赖或具有这种精神的东西......但据我了解,Boost 应该是可能的。
我们将不胜感激一些示例代码!谢谢
【问题讨论】:
imbue
不能与stringstream
一起使用吗? utf8 codecvt 方面到底出了什么问题?
看看***.com/questions/148403/…
wchar_t
/wstring
是保存代码点的错误选择,因为根本无法保证 wchar_t 足够宽(iirc,在 Windows 上它不适用于BMP。
【参考方案1】:
谢谢大家,但最终我求助于http://utfcpp.sourceforge.net/——这是一个非常轻量级且易于使用的纯标题库。我在这里分享一个演示代码,如果有人觉得它有用的话:
inline void decode_utf8(const std::string& bytes, std::wstring& wstr)
utf8::utf8to32(bytes.begin(), bytes.end(), std::back_inserter(wstr));
inline void encode_utf8(const std::wstring& wstr, std::string& bytes)
utf8::utf32to8(wstr.begin(), wstr.end(), std::back_inserter(bytes));
用法:
wstring ws(L"\u05e9\u05dc\u05d5\u05dd");
string s;
encode_utf8(ws, s);
【讨论】:
【参考方案2】:在 cmets 中已经有一个 boost 链接,但在几乎标准的 C++0x 中,有 wstring_convert
这样做
#include <iostream>
#include <string>
#include <locale>
#include <codecvt>
int main()
wchar_t uchars[] = 0x5e9, 0x5dc, 0x5d5, 0x5dd, 0;
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
std::string s = conv.to_bytes(uchars);
std::wstring ws2 = conv.from_bytes(s);
std::cout << std::boolalpha
<< (s == "\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d" ) << '\n'
<< (ws2 == uchars ) << '\n';
使用 MS Visual Studio 2010 EE SP1 或 CLang++ 2.9 编译时的输出
true
true
【讨论】:
还是不是跨平台的吗? C++11 到来之后? @Mikhail 到了,但是 GCC 还没有实现它。 为了更新答案,到目前为止std::codecvt_utf8
、std::wstring_convert
和家人是deprecated in C++17。您可以改用std::codecvt
。
@cbuchart 不是真的。为了鼓励 C++20 的替代方案,它们被弃用,别无选择。很像 std::strstream 在 C++98 中被弃用,并且仍然在标准中,别无选择。【参考方案3】:
Boost.Locale 在 Boost 1.48(2011 年 11 月 15 日)中发布,使其更容易从 UTF8/16 转换为 UTF8/16
以下是文档中的一些方便示例:
string utf8_string = to_utf<char>(latin1_string,"Latin1");
wstring wide_string = to_utf<wchar_t>(latin1_string,"Latin1");
string latin1_string = from_utf(wide_string,"Latin1");
string utf8_string2 = utf_to_utf<char>(wide_string);
几乎和 Python 编码/解码一样简单 :)
请注意,Boost.Locale 不是一个只有头文件的库。
【讨论】:
你能用这个库添加 decode_utf8 操作的例子吗? 你可以试试这个表格把utf-8解码成utf-16 wstring wide_string = to_utf有关处理 utf8 的 std::string
/std::wstring
的直接替换,请参阅 TINYUTF8。
与<codecvt>
结合使用,您可以将几乎所有编码从/到utf8 转换为utf8,然后您可以通过上述库处理这些编码。
【讨论】:
嗨@jakob-riedle!我有一个关于你的图书馆的小问题(顺便说一句,欣赏你在其中付出的优雅和大量的工作!)。你能看一下吗:***.com/questions/49716774/…?以上是关于C++ & Boost:编码/解码 UTF-8的主要内容,如果未能解决你的问题,请参考以下文章