Windows 中的 UTF-8

Posted

技术标签:

【中文标题】Windows 中的 UTF-8【英文标题】:UTF-8 in Windows 【发布时间】:2010-09-15 01:19:33 【问题描述】:

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

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

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

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

所有 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;

还有类似形式的东西可以转换回来。

【讨论】:

【参考方案2】:

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

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

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

【讨论】:

【参考方案3】:

使用 cygwin(默认提供 UTF-8 语言环境),或为 Windows 编写您自己的 libc hack,执行必要的 UTF-8 到 UTF-16 转换并包装非标准 _wfopen 等函数。

【讨论】:

真的吗?你会建议吗?【参考方案4】:

2018 年更新:Windows 10 分两步使“65001”代码页减少了“伪”:

    conhost 更改:适用于 Linux 的 Windows 子系统对其控制台使用代码页 65001。从 WSL 开始,也可以在 cmd.exe 中运行 chcp 65001。 (引起了一些pretty dumb Python bugs。) 全功能区域设置:Windows 自 build 17035 allows setting UTF-8 as the locale codepage。这可从 2018 年 4 月的更新中获得。

【讨论】:

以上是关于Windows 中的 UTF-8的主要内容,如果未能解决你的问题,请参考以下文章

IntelliJ IDEA 中文乱码配置

如何解决linux上有中文命名的文件名压缩后下载到windows上再解压出来都是乱码?

如何解决linux上有中文命名的文件名压缩后下载到windows上再解压出来都是乱码?

把windows中的D区挂载到LINUX中的/abc目录下

windows phone 或 windows 开发中的 inflate 模拟是啥?

Windows 8/Windows 2012 中的 VB6“IsNumeric()”行为