web-dev-qa-db-ja.com

C ++&Boost:UTF-8のエンコード/デコード

私は非常に単純なタスクを実行しようとしています:ユニコード対応のwstringを取得して、それをUTF8バイトとしてエンコードされたstringに変換し、次に逆の方法を使用します:UTF8バイトを含むstringを取得して、ユニコード対応のwstring

問題は、クロスプラットフォームが必要であり、Boostで動作する必要があることです。そして、動作させる方法を理解できていないようです。私はからかってきました

何のファイルの代わりに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で可能になるはずです。

いくつかのサンプルコードをいただければ幸いです。ありがとう

21
sebulba

皆さんに感謝しますが、最終的に私は 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);
23
sebulba

コメントにはすでにブーストリンクがありますが、ほぼ標準の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
18
Cubbi

Boost.LocaleはBoost 1.48(2011年11月15日)でリリースされ、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 encoding/decoding :)とほぼ同じくらい簡単

Boost.Localeはヘッダーのみのライブラリではないことに注意してください。

11
Diaa Sami

Utf8を処理するstd::string/std::wstringドロップイン置換については、 TINYUTF8

<codecvt> と組み合わせると、utf8から/へのすべてのエンコーディングから/へのほとんどの変換が可能になり、それを上記のライブラリで処理できます。

2
Jakob Riedle