конвертировать из char в char16_t

Мой конфиг:

  • Компилятор: GNU GCC 4.8.2
  • Я компилирую с C ++ 11
  • платформа / ОС: Linux 64bit Ubuntu 14.04.1 LTS

У меня есть этот метод:

static inline std::u16string StringtoU16(const std::string &str) {
const size_t si = strlen(str.c_str());
char16_t cstr[si+1];
memset(cstr, 0, (si+1)*sizeof(char16_t));
const char* constSTR = str.c_str();
mbstate_t mbs;
memset (&mbs, 0, sizeof (mbs));//set shift state to the initial state
size_t ret = mbrtoc16 (cstr, constSTR, si, &mbs);
std::u16string wstr(cstr);
return wstr;
}

Я хочу преобразование между char в char16_T в значительной степени (через std :: string и std :: u16string для облегчения управления памятью), но независимо от размера входной переменной str, он вернет только первый символ. Если str = «Hello», он вернет «H». Я не уверен, что не так мой метод. Значение ret равно 1.

3

Решение

Я не знал, что mbrtoc16 () может обрабатывать только один символ за раз … что за черепаха. Вот тогда код, который я генерирую, и работает как шарм:

static inline std::u16string StringtoU16(const std::string &str) {
std::u16string wstr = u"";
char16_t c16str[3] = u"\0";
mbstate_t mbs;
for (const auto& it: str){
memset (&mbs, 0, sizeof (mbs));//set shift state to the initial state
memmove(c16str, u"\0\0\0", 3);
mbrtoc16 (c16str, &it, 3, &mbs);
wstr.append(std::u16string(c16str));
}//for
return wstr;
}

для его аналога (когда нужен один путь, рано или поздно понадобится другой путь):

static inline std::string U16toString(const std::u16string &wstr) {
std::string str = "";
char cstr[3] = "\0";
mbstate_t mbs;
for (const auto& it: wstr){
memset (&mbs, 0, sizeof (mbs));//set shift state to the initial state
memmove(cstr, "\0\0\0", 3);
c16rtomb (cstr, it, &mbs);
str.append(std::string(cstr));
}//for
return str;
}

Имейте в виду, что c16rtomb будет с потерями, если символ не может быть преобразован из char16_t в char (может закончиться печатью набора «?» В зависимости от вашей системы), но он будет работать без жалоб.

2

Другие решения

mbrtoc16 () преобразует один символ и возвращает количество многобайтовых символов, использованных для преобразования char16_t.

Чтобы осуществить это преобразование, общий подход:

A) позвоните mbrtoc16 ().

Б) сохранить преобразованный символ, пропустить количество символов, которые были использованы.

C) Вы использовали всю строку, которую хотели конвертировать? Если нет, вернитесь к шагу А.

Кроме того, могут быть ошибки преобразования. Вы должны проверить возвращаемое значение из mbrtoc16 () и делать все, что хотите, для обработки ошибок преобразования (исходная многобайтовая строка является действительной).

Наконец, вы не должны предполагать, что максимальный размер строки char16_t будет равен или меньше размера многобайтовой строки. Это, вероятно, есть; но в какой-то странной локали я предполагаю, что теоретически это может быть больше.

0