Windows中的UTF-8

时间:2020-03-06 15:04:16  来源:igfitidea点击:

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

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

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

我该如何解决?

解决方案

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

并转换成类似形式的东西。

不幸的是,没有办法使Unicode成为Windows中的当前代码页。 CP_UTF7和CP_UTF8常量是伪代码页,仅在MultiByteToWideChar和WideCharToMultiByte转换函数中使用,如Ben所述。

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

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