Преобразование японской wstring в std :: string - PullRequest
0 голосов
/ 16 июня 2020

Может ли кто-нибудь предложить хороший метод преобразования японского std::wstring в std::string?

Я использовал приведенный ниже код. Японские строки некорректно конвертируются в ОС Engli sh.

std::string WstringTostring(std::wstring str)
{
    size_t size = 0;
    _locale_t lc = _create_locale(LC_ALL, "ja.JP.utf8");
    errno_t err = _wcstombs_s_l(&size, NULL, 0, &str[0], _TRUNCATE, lc);
    std::string ret = std::string(size, 0);
    err = _wcstombs_s_l(&size, &ret[0], size, &str[0], _TRUNCATE, lc);
    _free_locale(lc);
    ret.resize(size-1);
    return ret;
}

wstring равно "C\\files\\ブ種別.pdf".

Преобразованный string равен "C:\\files\\ブ種別.pdf".

Ответы [ 2 ]

4 голосов
/ 16 июня 2020

Мне это действительно кажется правильным.

Это версия вашего ввода в кодировке UTF-8 (которая, по-видимому, была UTF-16 до преобразования), но показанная в ее ASCII-декодированной форме из-за ошибка где-то в вашей инструментальной цепочке.

Вам просто нужно откалибровать ваш файл / терминал / дисплей, чтобы выводить текст, как если бы это был UTF-8 (который есть).


Также помните, что std::string - это просто контейнер байтов, который по своей сути не определяет и не подразумевает какую-либо конкретную кодировку. Итак, ваш вопрос скорее «как мне преобразовать UTF-16 (содержащий японские символы) в UTF-8 в Windows» или, как выясняется, «как мне настроить мой терминал для отображения UTF-8?» *. 1009 *

Если вы отображаете эту строку в окне локальных переменных Visual Studio (что вы предлагаете в случае с вашим комментарием "Я наблюдал значение строки" ret "в локальном окне во время отладки" ) вам не повезло, потому что VS не знает, в какой кодировке находится ваша строка (и не пытается это выяснить).

Однако для других аспектов Visual Studio, таких как окно вывода консоли, существуют различные подходы для решения этой проблемы ( пример ).

0 голосов
/ 16 июня 2020

EDIT: сначала кое-что. Windows имеет понятие кодовой страницы ANSI. Это кодовая страница по умолчанию для строк, отличных от Unicode, которую предполагает Windows. Каждая программа, использующая не-Unicode версии Windows API и не указывающая кодовую страницу явно, использует кодовую страницу ANSI .

Кодовая страница ANSI определяется параметром «Система по умолчанию locale "в Панели управления. По состоянию на Windows 10 мая 2020 года он находится в разделе «Регион / Администрация / Изменить язык системы». Для изменения этого параметра требуются права администратора.

По умолчанию Windows с установленным системным языком по умолчанию на английский sh использует кодовую страницу 1252 в качестве кодовой страницы ANSI. Эта кодовая страница не содержит японских символов. Таким образом, использование японского языка в программах, не знающих Unicode, в этой ситуации сложно или невозможно.

Похоже, OP хочет или должен использовать часть третья часть кода C ++, использующего многобайтовые строки (std::string и / или char*). Это не обязательно означает, что он не знает Unicode, но может. То, что пытается сделать OP, полностью зависит от способа кодирования сторонней библиотеки. Это может быть вообще невозможно.


Похоже, ваша проблема в том, что какая-то часть стороннего кода ожидает имя файла в ANSI и использует функции ANSI для открытия этого файла. В системе Engli sh со значением по умолчанию для системной локали японский язык не может быть преобразован в ANSI, потому что кодовая страница ANSI (CP1252 на практике) не содержит японских символов.

What I подумайте, что вам следует сделать, вы должны получить короткое имя файла вместо GetShortPathNameW, преобразовать этот путь к файлу в ANSI и передать эту строку. Примерно так:

std::string WstringFilenameTostring(std::wstring str)
{
    wchar_t ShortPath[MAX_PATH+1];
    DWORD dw = GetShortPathNameW(str.c_str(), ShortPath, _countof(ShortPath));

    char AnsiPath[MAX_PATH+1];
    int n = WideCharToMultiByte(CP_ACP, 0, ShortPath, -1, AnsiPath, _countof(AnsiPath), 0, 0);
    return string(AnsiPath);
}

Это код только для имен файлов . Для любой другой японской строки он вернет ерунду. В моем тесте он преобразовал "日本語 .txt" во что-то нечитаемое, но буквенно-цифровое c:)

...