46

我刚刚开始进行一些编程,以在 WinXP 系统上处理具有非英文名称的文件名。我已经完成了一些关于 unicode 的推荐阅读,我想我明白了基本的想法,但有些部分对我来说仍然不是很清楚。

具体来说,存储在 NTFS 中的文件名(不是内容,而是文件的实际名称)是什么编码(UTF-8、UTF-16LE/BE) ?是否可以使用 fopen() 打开任何文件,它需要一个 char*,或者我别无选择,只能使用 wfopen(),它使用一个 wchar_t*,并且可能需要一个 UTF-16 字符串?

我尝试手动将 UTF-8 编码的字符串输入 fopen(),例如。

unsigned char filename[] = {0xEA, 0xB0, 0x80, 0x2E, 0x74, 0x78, 0x74, 0x0}; // 가.txt

FILE* f = fopen((char*)filename, "wb+");

但这以“ê°€.txt”的形式出现。

我的印象(可能是错误的)UTF8 编码的字符串足以在 Windows 下打开任何文件名,因为我似乎模糊地记得一些 Windows 应用程序传递 (char*),而不是 (wchar_t*),并且有没问题。

任何人都可以对此有所了解吗?

4

3 回答 3

39

NTFS 以 UTF-16 存储文件名,但fopen使用的是 ANSI(不是 UTF-8)。

为了使用 UTF16 编码的文件名,您需要使用文件打开调用的 Unicode 版本。通过在您的项目中定义UNICODE和来做到这一点。_UNICODE然后使用CreateFile调用或wfopen调用。

于 2010-01-12T17:38:33.903 回答
15

fopen() - 在 Windows 上的 MSVC 中(默认情况下)不采用 utf-8 编码的 char*。

不幸的是,utf-8 是最近在伟大的计划中发明的。Windows API 分为 Unicode 和 Ansi 版本。每个接受或处理字符串的 Windows api 实际上都带有 W 或 A 后缀 - W 表示“宽”字符/Unicode,A 表示 Ansi。宏魔术将所有这些隐藏在开发人员之外,因此您只需根据您的构建配置使用 char* 或 wchar_t* 调用 CreateFile,而无需知道其中的区别。

'Ansi' 编码实际上不是特定的编码:- 但意味着用于“char”字符串的编码特定于 PC 的区域设置。

现在,因为 c-runtime 函数(如 fopen)需要在没有开发人员知识的情况下默认工作 - 在 Windows 系统上,他们希望以 Windows 本地编码接收字符串。msdn 表示 microsoft c-runtime api setlocal 可以更改当前线程的语言环境——但特别指出,对于每个字符需要超过 2 个字节的任何语言环境——比如 utf-8,它将失败。

因此,在 Windows 上没有快捷方式。您需要使用 wfopen 或原生 API CreateFileW(或使用 Unicode 构建设置创建项目并调用 Createfile)和 wchar_t* 字符串。

于 2010-01-12T18:20:44.847 回答
8
于 2014-11-07T14:22:28.740 回答