如何在C Windows程序中将代码页设置为UTF-8?

我有第三方库,它使用fopen打开文件。我可以使用wcstombs将我的Unicode文件名转换为当前代码页,但是如果用户的文件名在代码页之外有一个字符,则会中断。

理想情况下,我只需调用_setmbcp(65001)将代码页设置为UTF-8,但_setmbcp的MSDN文档声明不支持UTF-8。

我怎样才能解决这个问题?

有帮助吗?

解决方案

不幸的是,没有办法让Unicode成为Windows中的当前代码页。 CP_UTF7 CP_UTF8 常量是伪代码页,仅在 MultiByteToWideChar WideCharToMultiByte 转换函数,就像Ben提到的那样。

您的问题类似于fstream C ++类。 fstream构造函数只接受 char * 名称,因此无法打开具有真正Unicode名称的文件。 VC提供的唯一解决方案是黑客攻击:单独打开文件,然后将句柄设置为流对象。当然,我担心这不是你的选择,因为第三方库可能不接受句柄。

我能想到的唯一解决方案是创建一个非Unicode名称的临时文件,该文件与原始名称硬链接,并将其用作参数。

其他提示

所有Windows API都以UTF-16为基础,因此您最好在您的库周围编写一个包装器,以便在边界处进行转换。

奇怪的是,Windows认为UTF-8是用于转换目的的代码页,因此您使用与在代码页之间转换相同的API:

std::wstring Utf8ToUtf16(const char* u8string)
{
    int wcharcount = strlen(u8string);
    wchar_t *tempWstr = new wchar_t[wcharcount];
    MultiByteToWideChar(CP_UTF8, 0, u8string, -1, tempWstr, wcharcount);
    wstring w(tempWstr);
    delete [] tempWstr;
    return w;
}

还有类似的形式可以转换回去。

2018年更新:Windows 10已经制作了“65001”。代码页少“伪”分两步:

  1. conhost 更改:适用于Linux的Windows子系统使用代码页65001作为其控制台。自WSL以来,也可以在 cmd.exe 中运行 chcp 65001 。 (它导致了一些非常愚蠢的Python错误。)
  2. 全功能区域设置:自17035版本以来的Windows 允许将UTF-8设置为区域设置代码页。这可以从2018年4月的更新中获得。

使用cygwin(默认情况下提供UTF-8语言环境),或编写自己的libc hack for Windows,执行必要的UTF-8到UTF-16翻译并包装非标准的 _wfopen 等功能。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top