LINUX.ORG.RU

Можно ли как-то, и как, в C++ получить std::locale UTF-8 без указания языка_региона?

 , ,


0

1

Допустим мне нужен UTF-8, но без разницы какой язык и регион, например, для того, что бы конвертировать текст между UTF-8 и wchar_t. Мой код не знает и не хочет знать какие там язык и регион, просто получить UTF-8, а остальные параметры по умолчанию. На офтопике, к примеру, можно позвать std::locale(«.UTF-8»), и это работает, но мне нужно кроссплатформенно, или хотя бы для GNU/Linux. Такое возможно?

★★★

Нет, наличие в системе локали с поддержкой UTF-8 не гарантировано даже на GNU/Linux, не говоря уже о произвольной POSIX-совместимой ОС.

Де-факто, wchar_t в наши дни содержит номера Unicode code points. Де-юре, это тоже не гарантировано; кроме того, тесты на CRAN показывали, что это предположение ломалось на некоторых версиях Solaris.

Вы можете попробовать GNU libiconv, но преобразование в wchar_t там работает через определённые костыли, впрочем, портированные на самые разные ОС. Вы также можете попробовать libicu и делать всё в UTF-8, не трогая wchar_t.

anonymous
()

Лучше не играть с setlocale(), а использовать std::wstring_convert и std::codecvt_utf8:

std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
auto ws = converter.from_bytes(u8"Привет");
auto u8s = converter.to_bytes(ws);
iliyap ★★★★★
()
Ответ на: комментарий от iliyap

std::codecvt

Оно же deprecated. Мне вот тоже надо, ищу актуальный вариант на замену и не нахожу.

codecvt_utf8 (C++11) (deprecated in C++17) (removed in C++26)

Loki13 ★★★★★
()

Ну укажи en_US.UTF-8, американская локаль по-любому везде будет, а если не будет - пускай пользователь её установит.

vbr ★★★★★
()
Ответ на: комментарий от dataman

Зато добавили text_encoding.

Это конечно радует. Но выходит, что при переходе на С++26 придется переписывать код.

Например, uni-algo 0.8.0 - библиотека алгоритмов Unicode для C++.

А это спасибо.

Loki13 ★★★★★
()
Последнее исправление: Loki13 (всего исправлений: 1)

строго говоря, ширина wchar_t зависит от компилятора (и платформы) и не является универсальной. стандартизированы только char16_t и char32_t.

Iron_Bug ★★★★★
()
Ответ на: комментарий от vbr

Ну укажи en_US.UTF-8, американская локаль по-любому везде будет, а если не будет - пускай пользователь её установит.

Матерь божья, ну кто же так делает?

anonymous
()
Ответ на: комментарий от normann

C.UTF-8 на линуксе попробуй.

Ну впринципе сработало. Спасибо.

Сработало, да не везде. Пришлось откатиться на en_US.utf8

normann ★★★
() автор топика
Ответ на: комментарий от anonymous

А что не так? И какие альтернативы лучше?

normann ★★★
() автор топика

не используй локали, если хочешь, чтобы твоим софтом можно было пользоваться на разных системах (или хотя бы портировать на них) без матюков.
Скорее всего если тебе откуда-то пришёл wchar_t и это не платформозависимый код (unicode функции из winapi - ок) - то ты уже сделал что-то не так. Ну или разраб библиотеки, с которой работаешь

mittorn ★★★★★
()
6 сентября 2025 г.

std::mbrtoc8 и std::c8rtomb (since C++20)

safocl ★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.