Size: a a a

2020 April 10

M

MDenis2k in pro.cxx
Буста нет для Билдера (есть но урезанный до невозможности и старая версия). А так ок - тоже попробуем.
источник

DF

Dollar Føølish in pro.cxx
А как из буста вытащить утф16?
источник

DF

Dollar Føølish in pro.cxx
Там оно есть штоле?
источник

DV

Dmitrij V in pro.cxx
MDenis2k
Подскажите кросплатформенную библиотеку конвертации ansi-utf8-utf16. Желательно небольшую (не буст) (используем c++11 стандарт)
держи:

inline std::string u16_to_u8(const std::wstring& s) noexcept {
 std::string ret;
 #if defined(_WIN32)
 // https://forum.sources.ru/index.php?showtopic=291288&st=15
 int len = ::WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, nullptr, 0, nullptr, nullptr);
 if (len > 0) {
   ret.resize(len);
   if (std::size(ret) != static_cast<std::size_t>(len)) { return ret; }
   ::WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, std::data(ret), len, nullptr, nullptr);
 }
 #else
 try {
   // https://stackoverflow.com/questions/7153935/how-to-convert-utf-8-stdstring-to-utf-16-stdwstring
   //ret = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(s);
   ret = std::wstring_convert<std::codecvt_utf8<wchar_t>>{}.to_bytes(s);
 } catch (...) {}
 #endif
 return ret;
}

inline std::wstring u8_to_u16(const std::string& s) noexcept {
 std::wstring ret;
 #if defined(_WIN32)
 // https://forum.sources.ru/index.php?showtopic=291288&st=15
 int len = ::MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0);
 if (len > 0) {
   ret.resize(len);
   if (std::size(ret) != static_cast<std::size_t>(len)) { return ret; }
   ::MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, std::data(ret), len);
 }
 #else
 try {
   // https://stackoverflow.com/questions/7153935/how-to-convert-utf-8-stdstring-to-utf-16-stdwstring
   //ret = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(s);
   ret = std::wstring_convert<std::codecvt_utf8<wchar_t>>{}.from_bytes(s);
 } catch (...) {}
 #endif
 return ret;
}
источник

YH

Yuri Hudobin in pro.cxx
codecvt вроде же забанили в текущем стандарте?
источник

DV

Dmitrij V in pro.cxx
Yuri Hudobin
codecvt вроде же забанили в текущем стандарте?
помечено деприкейт с 17
источник

PK

Pavel Kazakov in pro.cxx
Yuri Hudobin
codecvt вроде же забанили в текущем стандарте?
Линкану свой же вопрос))
https://stackoverflow.com/q/42946335
источник

YH

Yuri Hudobin in pro.cxx
Правильное решение использовать функцию конвертации с промежуточным utf32. Только вот никто не предложил стандартную реализацию. Приходится велосипедить, вытягивая крохи кода из интернета. Iconv и ICU все же для других целей и в таких задачах избыточны.
источник

DV

Dmitrij V in pro.cxx
Немного уродливо, но привычка в своем коде стремиться к компактности (знаю что не гуд):

inline std::wstring u8_to_u32(const std::string& s) noexcept {
 // https://gist.github.com/rechardchen/3321830
 std::wstring ret;
 ret.reserve(std::size(s));
 wchar_t wc{0};
 for (const char* p = std::data(s), *e = std::data(s)+std::size(s); p && p < e && *p; ) {
   if ((*p & 0x80) == 0) { wc = *p; ++p; }
   else if ((*p & 0xE0) == 0xC0) { wc = (*p & 0x1F) << 6; wc |= (*(p+1) & 0x3F); p += 2; }
   else if ((*p & 0xF0) == 0xE0) { wc = (*p & 0xF) << 12; wc |= (*(p+1) & 0x3F) << 6; wc |= (*(p+2) & 0x3F); p += 3; }
   else if ((*p & 0xF8) == 0xF0) { wc = (*p & 0x7) << 18; wc |= (*(p+1) & 0x3F) << 12; wc |= (*(p+2) & 0x3F) << 6; wc |= (*(p+3) & 0x3F); p += 4; }
   else if ((*p & 0xFC) == 0xF8) { wc = (*p & 0x3) << 24; wc |= (*p & 0x3F) << 18; wc |= (*p & 0x3F) << 12; wc |= (*p & 0x3F) << 6; wc |= (*p & 0x3F); p += 5; }
   else if ((*p & 0xFE) == 0xFC) { wc = (*p & 0x1) << 30; wc |= (*p & 0x3F) << 24; wc |= (*p & 0x3F) << 18; wc |= (*p & 0x3F) << 12; wc |= (*p & 0x3F) << 6; wc |= (*p & 0x3F); p += 6; }
   ret += wc;
 } return ret;
}

inline std::string u32_to_u8(const std::wstring& s) noexcept {
 // https://gist.github.com/rechardchen/3321830
 std::string ret;
 ret.reserve(std::size(s)*4);
 for (auto p = std::begin(s), e = std::end(s); p != e; ++p) {
   wchar_t wc = *p;
   if (0 <= wc && wc <= 0x7f) { ret += (char)wc; }
   else if (0x80 <= wc && wc <= 0x7ff) { ret += (0xc0 | (wc >> 6)); ret += (0x80 | (wc & 0x3f)); }
   else if (0x800 <= wc && wc <= 0xffff) { ret += (0xe0| (wc >> 12)); ret += (0x80| ((wc >> 6) & 0x3f)); ret += (0x80| (wc & 0x3f)); }
   else if (0x10000 <= wc && wc <= 0x1fffff) { ret += (0xf0 | (wc >> 18)); ret += (0x80 | ((wc >> 12) & 0x3f)); ret += (0x80 | ((wc >> 6) & 0x3f)); ret += (0x80 | (wc & 0x3f)); }
   else if (0x200000 <= wc && wc <= 0x3ffffff) { ret += (0xf8 | (wc >> 24)); ret += (0x80 | ((wc >> 18) & 0x3f)); ret += (0x80 | ((wc >> 12) & 0x3f)); ret += (0x80 | ((wc >> 6) & 0x3f)); ret += (0x80 | (wc & 0x3f)); }
   else if (0x4000000 <= wc && wc <= 0x7fffffff) { ret += (0xfc | (wc >> 30)); ret += (0x80 | ((wc >> 24) & 0x3f)); ret += (0x80 | ((wc >> 18) & 0x3f)); ret += (0x80 | ((wc >> 12) & 0x3f)); ret += (0x80 | ((wc >> 6) & 0x3f)); ret += (0x80 | (wc & 0x3f)); }
 } return ret;
}
источник

YH

Yuri Hudobin in pro.cxx
Dmitrij V
Немного уродливо, но привычка в своем коде стремиться к компактности (знаю что не гуд):

inline std::wstring u8_to_u32(const std::string& s) noexcept {
 // https://gist.github.com/rechardchen/3321830
 std::wstring ret;
 ret.reserve(std::size(s));
 wchar_t wc{0};
 for (const char* p = std::data(s), *e = std::data(s)+std::size(s); p && p < e && *p; ) {
   if ((*p & 0x80) == 0) { wc = *p; ++p; }
   else if ((*p & 0xE0) == 0xC0) { wc = (*p & 0x1F) << 6; wc |= (*(p+1) & 0x3F); p += 2; }
   else if ((*p & 0xF0) == 0xE0) { wc = (*p & 0xF) << 12; wc |= (*(p+1) & 0x3F) << 6; wc |= (*(p+2) & 0x3F); p += 3; }
   else if ((*p & 0xF8) == 0xF0) { wc = (*p & 0x7) << 18; wc |= (*(p+1) & 0x3F) << 12; wc |= (*(p+2) & 0x3F) << 6; wc |= (*(p+3) & 0x3F); p += 4; }
   else if ((*p & 0xFC) == 0xF8) { wc = (*p & 0x3) << 24; wc |= (*p & 0x3F) << 18; wc |= (*p & 0x3F) << 12; wc |= (*p & 0x3F) << 6; wc |= (*p & 0x3F); p += 5; }
   else if ((*p & 0xFE) == 0xFC) { wc = (*p & 0x1) << 30; wc |= (*p & 0x3F) << 24; wc |= (*p & 0x3F) << 18; wc |= (*p & 0x3F) << 12; wc |= (*p & 0x3F) << 6; wc |= (*p & 0x3F); p += 6; }
   ret += wc;
 } return ret;
}

inline std::string u32_to_u8(const std::wstring& s) noexcept {
 // https://gist.github.com/rechardchen/3321830
 std::string ret;
 ret.reserve(std::size(s)*4);
 for (auto p = std::begin(s), e = std::end(s); p != e; ++p) {
   wchar_t wc = *p;
   if (0 <= wc && wc <= 0x7f) { ret += (char)wc; }
   else if (0x80 <= wc && wc <= 0x7ff) { ret += (0xc0 | (wc >> 6)); ret += (0x80 | (wc & 0x3f)); }
   else if (0x800 <= wc && wc <= 0xffff) { ret += (0xe0| (wc >> 12)); ret += (0x80| ((wc >> 6) & 0x3f)); ret += (0x80| (wc & 0x3f)); }
   else if (0x10000 <= wc && wc <= 0x1fffff) { ret += (0xf0 | (wc >> 18)); ret += (0x80 | ((wc >> 12) & 0x3f)); ret += (0x80 | ((wc >> 6) & 0x3f)); ret += (0x80 | (wc & 0x3f)); }
   else if (0x200000 <= wc && wc <= 0x3ffffff) { ret += (0xf8 | (wc >> 24)); ret += (0x80 | ((wc >> 18) & 0x3f)); ret += (0x80 | ((wc >> 12) & 0x3f)); ret += (0x80 | ((wc >> 6) & 0x3f)); ret += (0x80 | (wc & 0x3f)); }
   else if (0x4000000 <= wc && wc <= 0x7fffffff) { ret += (0xfc | (wc >> 30)); ret += (0x80 | ((wc >> 24) & 0x3f)); ret += (0x80 | ((wc >> 18) & 0x3f)); ret += (0x80 | ((wc >> 12) & 0x3f)); ret += (0x80 | ((wc >> 6) & 0x3f)); ret += (0x80 | (wc & 0x3f)); }
 } return ret;
}
Так у всех получается не лучше %) Как этот код отреагирует на ill-formed последовательности utf8?
источник

АР

Андрей Руссков in pro.cxx
Yuri Hudobin
Так у всех получается не лучше %) Как этот код отреагирует на ill-formed последовательности utf8?
возможно, он даст тебе о них знать )
источник

AB

Artöm Bakri Al-Sarmini in pro.cxx
Dmitrij V
Немного уродливо, но привычка в своем коде стремиться к компактности (знаю что не гуд):

inline std::wstring u8_to_u32(const std::string& s) noexcept {
 // https://gist.github.com/rechardchen/3321830
 std::wstring ret;
 ret.reserve(std::size(s));
 wchar_t wc{0};
 for (const char* p = std::data(s), *e = std::data(s)+std::size(s); p && p < e && *p; ) {
   if ((*p & 0x80) == 0) { wc = *p; ++p; }
   else if ((*p & 0xE0) == 0xC0) { wc = (*p & 0x1F) << 6; wc |= (*(p+1) & 0x3F); p += 2; }
   else if ((*p & 0xF0) == 0xE0) { wc = (*p & 0xF) << 12; wc |= (*(p+1) & 0x3F) << 6; wc |= (*(p+2) & 0x3F); p += 3; }
   else if ((*p & 0xF8) == 0xF0) { wc = (*p & 0x7) << 18; wc |= (*(p+1) & 0x3F) << 12; wc |= (*(p+2) & 0x3F) << 6; wc |= (*(p+3) & 0x3F); p += 4; }
   else if ((*p & 0xFC) == 0xF8) { wc = (*p & 0x3) << 24; wc |= (*p & 0x3F) << 18; wc |= (*p & 0x3F) << 12; wc |= (*p & 0x3F) << 6; wc |= (*p & 0x3F); p += 5; }
   else if ((*p & 0xFE) == 0xFC) { wc = (*p & 0x1) << 30; wc |= (*p & 0x3F) << 24; wc |= (*p & 0x3F) << 18; wc |= (*p & 0x3F) << 12; wc |= (*p & 0x3F) << 6; wc |= (*p & 0x3F); p += 6; }
   ret += wc;
 } return ret;
}

inline std::string u32_to_u8(const std::wstring& s) noexcept {
 // https://gist.github.com/rechardchen/3321830
 std::string ret;
 ret.reserve(std::size(s)*4);
 for (auto p = std::begin(s), e = std::end(s); p != e; ++p) {
   wchar_t wc = *p;
   if (0 <= wc && wc <= 0x7f) { ret += (char)wc; }
   else if (0x80 <= wc && wc <= 0x7ff) { ret += (0xc0 | (wc >> 6)); ret += (0x80 | (wc & 0x3f)); }
   else if (0x800 <= wc && wc <= 0xffff) { ret += (0xe0| (wc >> 12)); ret += (0x80| ((wc >> 6) & 0x3f)); ret += (0x80| (wc & 0x3f)); }
   else if (0x10000 <= wc && wc <= 0x1fffff) { ret += (0xf0 | (wc >> 18)); ret += (0x80 | ((wc >> 12) & 0x3f)); ret += (0x80 | ((wc >> 6) & 0x3f)); ret += (0x80 | (wc & 0x3f)); }
   else if (0x200000 <= wc && wc <= 0x3ffffff) { ret += (0xf8 | (wc >> 24)); ret += (0x80 | ((wc >> 18) & 0x3f)); ret += (0x80 | ((wc >> 12) & 0x3f)); ret += (0x80 | ((wc >> 6) & 0x3f)); ret += (0x80 | (wc & 0x3f)); }
   else if (0x4000000 <= wc && wc <= 0x7fffffff) { ret += (0xfc | (wc >> 30)); ret += (0x80 | ((wc >> 24) & 0x3f)); ret += (0x80 | ((wc >> 18) & 0x3f)); ret += (0x80 | ((wc >> 12) & 0x3f)); ret += (0x80 | ((wc >> 6) & 0x3f)); ret += (0x80 | (wc & 0x3f)); }
 } return ret;
}
> *(p + 1)
Зачем?
источник

DV

Dmitrij V in pro.cxx
Yuri Hudobin
Так у всех получается не лучше %) Как этот код отреагирует на ill-formed последовательности utf8?
хз, этот код заготовлен "на будущее", не тестировал ещё (у меня везде utf8)
источник

YH

Yuri Hudobin in pro.cxx
Dmitrij V
хз, этот код заготовлен "на будущее", не тестировал ещё (у меня везде utf8)
Второй недостаток — под виндовз wchar_t не 32-разрядные.
источник

DV

Dmitrij V in pro.cxx
Artöm Bakri Al-Sarmini
> *(p + 1)
Зачем?
ссылка на оригинал предоставлена (ты же догадался что это адаптированная копипаста, я надеюсь):

https://gist.github.com/rechardchen/3321830
источник

AB

Artöm Bakri Al-Sarmini in pro.cxx
В чем адаптация здесь?
источник

YH

Yuri Hudobin in pro.cxx
Я этот код года полтора назад выкладывал. Еще раз поделюсь. https://pastebin.com/bEpfQ1TX
источник

DV

Dmitrij V in pro.cxx
Yuri Hudobin
Я этот код года полтора назад выкладывал. Еще раз поделюсь. https://pastebin.com/bEpfQ1TX
нормально )) спс
источник

in pro.cxx
Привет. А как правильно прочитать файл в utf8 посимвольно в чистом c?
источник

in pro.cxx
wchar_t и ко?
источник