c ++ конвертировать из UTF-8 в wstring, используя iconv - PullRequest
2 голосов
/ 30 марта 2011

У меня есть приложение Linux C ++, которое запускает следующее:

int main()
{
  using namespace std;
  char str[] = "¡Hola!";

  wchar_t wstr[50];

  size_t rc;

  memset(wstr, 0, sizeof(wstr));

  rc = mbstowcs(wstr, str, 50);

  cout << "mbstowcs results: ";
  cout << "rc = " << rc << endl;
  cout << "str:" << str  << endl;
  wcout << L"wstr:" << wstr  << endl;
  setlocale(LC_CTYPE,"");
  iconv_t cd = iconv_open("WCHAR_T", "UTF-8");
  cout << "iconv_open errno = "<< errno << endl;

  char *s = str;
  char *t = (char *)wstr;
  size_t s1 = strlen(str);
  size_t s2 = 50;

  rc = iconv(cd, &s, &s1, &t, &s2);

  cout << "iconv results: ";
  cout << "rc = " << rc << endl;
  cout << "str:" << str  << endl;
  wcout << L"wstr:" << wstr  << endl;

}

Я хочу преобразовать вектор символов UTF-8 в wstring, но приведенный выше код возвращает этот результат:

 mbstowcs results: rc = 18446744073709551615
    str:¡Hola!
    wstr:
    iconv_open errno = 2
    iconv results: rc = 0
    str:¡Hola!
    wstr:�Hola!

iconv result конвертирует первый символ в другой.

Примечание: если я заменю WCHAR_T в UCS-4 -INTERNAL, wstr ничего не содержит.

любая помощь?

спасибо!

Ответы [ 2 ]

0 голосов
/ 30 марта 2011

Не глядя на документацию iconv (до сих пор никогда не использовал ее), я ожидал бы, что ваш ввод (char str[] = "¡Hola!";) не будет закодирован как многобайтовая строка - это скорее простая строка ANSI, использующая вашу локальную / текущую кодовую страницу представлять '¡'. Или другими словами: в вашей существующей строке (с использованием const char[]) '¡' хранится в одном байте со значением где-то выше 127. mbstowcs() однако можно ожидать, что он будет использовать, возможно, 2 байта для представления правильного '¡' (пока не проверял это), и значение, используемое вами '¡', может даже быть чем-то непредвиденным / недопустимым.

Я ожидаю, что там произойдет ошибка, так как mbcstowcs() должен возвращать количество символов в преобразованной строке - но "18446744073709551615" просто слишком длинный. Если это так, вы также должны иметь возможность правильно использовать iconv при определении собственной широкой строки с правильным текстом и использовать ее вместо этого (wchar_t wstr[] = L"¡Hola!";).

0 голосов
/ 30 марта 2011

Можно ли использовать буст?

http://www.boost.org/doc/libs/1_46_1/libs/serialization/doc/codecvt.html

...