Массив символов UTF8 в std::wstring

Я просто пытаюсь получить заголовок окна x11 и сохранить его в std::wstring. Я использую такую ​​команду, чтобы получить заголовок

auto req_title = xcb_get_property(conn, 0, window, XCB_ATOM_WM_NAME, XCB_GET_PROPERTY_TYPE_ANY, 0, 100);
auto res_title = xcb_get_property_reply(conn, req_title, nullptr);

После этого я могу получить заголовок, хранящийся в массиве символов. Как я могу преобразовать этот массив в wstring?


person Zakhar Kurasov    schedule 06.11.2018    source источник
comment
Этот ответ может быть полезен: заголовок stackoverflow.com/questions/43302279/   -  person Galik    schedule 06.11.2018
comment
Почему? Что вы можете сделать с массивом wchar в Unix?   -  person n. 1.8e9-where's-my-share m.    schedule 06.11.2018


Ответы (1)


Текущее решение

Вы можете использовать std::wstring_convert, чтобы преобразовать string в или из wstring, используя codecvt для указания выполняемого преобразования .

Пример использования:

string so=u8"Jérôme Ângle"; 
wstring st; 
wstring_convert<std::codecvt_utf8<wchar_t>,wchar_t> converter;
st = converter.from_bytes(so);

Если у вас есть c-строка (массив символов), перегрузки from_bytes() будут делать именно то, что вы хотите:

char p[]=u8"Jérôme Ângle";
wstring ws = converter.from_bytes(p);

Онлайн-демонстрация

Это устойчиво?

Как указано в комментариях, C++17 устарел codecvt и утилита wstring_convert :

Эти функции трудно использовать правильно, и есть сомнения, правильно ли они указаны. Вместо этого пользователям следует использовать специальные библиотеки для обработки текста.

Кроме того, wstring основан на wchar_t, кодировка которого в системах Linux и Windows сильно различается.

Итак, первый вопрос — зачем вообще нужен wstring и почему бы просто не оставить utf-8 везде.

В зависимости от причин, вы можете рассмотреть возможность использования:

  • ICU и его UnicodeString для полной и всесторонней поддержки Unicode.
  • boost.locale и его to_utf или utf_to_utf, для общие задачи, связанные с юникодом.
  • utf8-cpp для работы со строками utf8 способом юникода (внимание, кажется, не поддерживается).
person Christophe    schedule 06.11.2018
comment
Обратите внимание, что wstring_convert, wbuffer_convert и codecvt_utf8 устарели в C++17. - person n. 1.8e9-where's-my-share m.; 06.11.2018
comment
from_bytes() имеет перегрузки, которые принимают строку char* с завершающим нулем, и два итератора char*, обозначающие диапазон, поэтому вам не нужно оборачивать ваши char данные во временную std::string, если она не зародилась таким образом с самого начала. - person Remy Lebeau; 06.11.2018
comment
@Christophe IMO, просто оберните код std::wstring_convert в аккуратные маленькие функции (например, utf8_to_ws(...) и ws_to_utf8(...)). Тогда вы не будете распространять его использование во всех приложениях. Затем, когда он будет изменен, вам нужно будет изменить только одну функцию, а не весь код. - person Galik; 06.11.2018
comment
@RemyLebeau спасибо, что указали на это! Я отредактировал соответственно. - person Christophe; 06.11.2018
comment
@Галик мудрая мысль! Особенно, когда я прочитал Пользователи должны вместо этого использовать специализированные библиотеки обработки текста в рабочий документ комитета по стандартам - person Christophe; 06.11.2018
comment
@н.м. Я полагаю, вы имеете в виду utf-8 везде :-) - person Christophe; 06.11.2018
comment
utf-8 везде — действительно отличная статья, но вам не нужно следовать ей неукоснительно, просто отойдите от wchar_t, вот и все. - person n. 1.8e9-where's-my-share m.; 06.11.2018
comment
Я на С++ 17, это не скомпилируется. Мне нужен wchar_t, потому что я использую библиотеки Windows. Должно быть решение, которое компилируется в визуальной студии С++ 17, а это не так. - person camccar; 26.08.2019