在Windows中使用UTF-8

27

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

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

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

我该如何解决这个问题?

4个回答

26

很遗憾,在Windows中并没有办法将Unicode设置为当前的代码页。 CP_UTF7CP_UTF8 常量是伪代码页,仅在 MultiByteToWideCharWideCharToMultiByte 转换函数中使用,就像Ben提到的那样。

你的问题类似于C++ fstream 类。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更改:Windows子系统使用代码页65001作为其控制台。自WSL以来,也可以在cmd.exe中运行chcp 65001。(这引起了一些相当愚蠢的Python错误。)
  2. 完整特色区域设置:Windows自17035版本开始允许将UTF-8设置为区域设置代码页。这在2018年4月的更新中可用。

-2
使用cygwin(它默认提供UTF-8区域设置)或编写自己的libc hack for Windows,进行必要的UTF-8到UTF-16转换并包装非标准的_wfopen等函数。

3
真的吗?你打算提出那个建议吗? - user90843

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接