Windows 中的 UTF-8

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

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

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

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

我该如何解决这个问题?

c windows winapi unicode utf-8
4个回答
26
投票

不幸的是,无法使 Unicode 成为 Windows 中的当前代码页。

CP_UTF7
CP_UTF8
常量是伪代码页,仅在 MultiByteToWideCharWideCharToMultiByte 转换函数中使用,就像 Ben 提到的那样。

您的问题与 fstream C++ 类的问题类似。 fstream 构造函数仅接受

char*
名称,因此无法打开具有真正 Unicode 名称的文件。 VC 提供的唯一解决方案是 hack:单独打开文件,然后将句柄设置为流对象。当然,恐怕这不适合您,因为第三方库可能不接受句柄。

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


12
投票

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

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


6
投票

2018年更新:Windows 10分两步让“65001”代码页变得不那么“伪”:

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

-2
投票

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

_wfopen
等函数.

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