将日语wstring转换为std::string。

问题描述 投票:0回答:1

有谁能给我推荐一个好的方法来转换日本的 std::wstringstd::string?

我使用了下面的代码。日文字符串在英文操作系统上无法正常转换。

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".

c++ locale cjk wstring
1个回答
4
投票

实际上,我觉得是正确的。

那是你的输入的UTF-8编码版本(在转换前大概是UTF-16),但由于你的工具链中的某个地方出了错,所以以ASCII解码的形式显示。

你只需要校准你的fileterminaldisplay,将文本输出渲染成UTF-8(事实如此)。


另外,请记住 std::string 仅仅是一个字节的容器,并没有内在地指定或暗示任何特定的编码。所以你的问题更像是 "如何在Windows中把UTF-16(包含日文字符)转换成UTF-8",或者,事实证明,"如何配置我的终端来显示UTF-8?"。

如果你的这个字符串的显示是在Visual Studio locals窗口中(你的评论中建议是这样的情况 "我在调试时观察到本地窗口中 "ret "字符串的值"),你就不走运了,因为VS不知道你的字符串是用什么编码的(它也不试图找出)。

对于Visual Studio的其他方面,比如控制台输出窗口,有很多方法可以解决这个问题 (例子).


0
投票

EDIT:先说一些事情。Windows有ANSI代码页的概念。它是Windows假定的非Unicode字符串的默认codepage。每一个使用非Unicode版本的Windows API的程序,并没有明确指定codepage。使用ANSI代码页.

.ANSI代码页是由控制面板中的 "系统默认locale "设置驱动的。从Windows 10 2020年5月起,它在RegionAdministrativeChange system locale下。要有管理员权限才能更改该设置。

默认情况下,系统默认locale设置为英文的Windows会使用 编码页1252 作为ANSI代码页。该代码页不包含日语字符。 所以在这种情况下,在不懂Unicode的程序中使用日语是很困难的,甚至是不可能的。

看来,上位机想要或不得不使用一段使用多字节字符串的第三部分C++代码(std::stringchar*). 这不一定意味着它不知道Unicode,但有可能。OP想要做的事情完全取决于第三方库的编码方式。 这可能根本不可能。


看起来你的问题是一些第三方代码期望一个ANSI的文件名,并使用ANSI函数来打开该文件。在英文系统中,系统locale的默认值是日文,日文是无法转换成ANSI的,因为ANSI的代码页(实际是CP1252)不包含日文字符。

我认为你应该做的,你应该得到一个简短的文件名,而不是使用 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 "转换为不可读的字母数字:)

© www.soinside.com 2019 - 2024. All rights reserved.