C ++ & Boost: кодировать / декодировать UTF-8 - PullRequest
21 голосов
/ 26 мая 2011

Я пытаюсь выполнить очень простую задачу: взять wstring с поддержкой юникода и преобразовать его в string, закодированный в байтах UTF8, а затем наоборот: взять string, содержащий UTF8байт и преобразовать его в Unicode-осознаваемый 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.

SomeПример кода будет принята с благодарностью!Спасибо

Ответы [ 4 ]

23 голосов
/ 27 мая 2011

Спасибо всем, но в итоге я прибег к 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);
18 голосов
/ 26 мая 2011

В комментариях уже есть ссылка для повышения, но в почти стандартном 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
11 голосов
/ 08 октября 2012

Boost.Locale был выпущен в Boost 1.48 (15 ноября 2011 г.), что упрощает конвертацию из и в 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 не является библиотекой только для заголовков.

2 голосов
/ 30 ноября 2016

Для замены для std::string / std::wstring, которая обрабатывает utf8, см. TINYUTF8 .

В комбинациис помощью <codecvt> вы можете в значительной степени конвертировать из / в каждую кодировку из / в utf8, которую затем обрабатываете через вышеуказанную библиотеку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...