[英]How to read a file name containing 'œ' as character in C/C++ on windows
这篇文章不是这个帖子的重复: dirent not working with unicode
因为在这里我在不同的操作系统上使用它,而且我也不想做同样的事情。 另一个线程试图简单地计算文件,我想访问更复杂的文件名。
我正在尝试通过 Windows 10 操作系统上的文件名检索数据信息。
为此,我使用dirent.h
(外部 c 库,但在 c++ 中仍然非常有用)。
DIR* directory = opendir(path);
struct dirent* direntStruct;
if (directory != NULL)
{
while (direntStruct = readdir(directory))
{
cout << direntStruct->d_name << endl;
}
}
此代码能够检索位于特定文件夹中的所有文件名(一个一个)。 而且效果很好!
但是当它遇到一个包含字符 'œ' 的文件时,事情就会变得疯狂:
例子:
grosse blessure au cœur.txt
在我的程序中读取为:
GUODU0~6.TXT
我无法在字符串名称中找到原始数据,因为您可以看到我的字符串变量与当前文件名无关!
我可以重命名文件并且它可以工作,但我不想这样做,我只需要从该文件名中读取数据,这似乎是不可能的。 我怎样才能做到这一点?
在 Windows 上,您可以使用FindFirstFile()
或FindFirstFileEx()
后跟FindNextFile()
来读取返回文件名中带有 Unicode 的目录的内容。
短文件名
您收到的名称是 NTFS 为非 ascii 文件名生成的8.3 短文件名,因此不支持 unicode 的程序可以访问它们。
抱住dirent
如果 dirent 不支持 UTF-16,最好的办法可能是更改您的库。
但是,根据库的实现,您可能会很幸运:
添加/更改应用程序的清单以支持基于char
的 Windows API 中的 UTF-8。 这需要最新版本的 Windows 10。
请参阅 MSDN: 使用Windows - 应用程序 - UWP - 设计和 UI - 可用性 - 全球化和本地化下的 UTF-8 代码页。
使用setlocale
将 C++ 运行时的代码页设置为 UTF-8
我不推荐这个,我不知道这是否有效。
生活就是改变
使用std::filesystem
枚举目录内容。 可以在此处找到一个简单示例(请参阅“2017 年更新”)。
仅限 Windows
您可以使用FindFirstFileW
和FindNextFileW
作为支持 UTF16 字符串的平台 API。 但是,使用 std::filesystem 几乎没有理由这样做(至少对于您的用例而言)。
如果您使用 C,请直接使用操作系统函数,特别是FindFirstFileW
和FindNextFileW
。 请注意末尾的W
,您希望使用这些函数的宽版本来获取完整的非 ASCII 名称。
在 C++ 中,您有更多选择,尤其是 Boost。 你有像recursive_directory_iterator
这样的类允许跨平台文件搜索,它们提供 UTF-8/UTF-16 文件名。
编辑:为了绝对清楚,您从原始代码中获得的文件名是正确的。 由于 Windows 文件系统(FAT32 和 NTFS)的向后兼容性,每个文件都有两个名称:“完整”、Unicode 识别名称和 DOS 时代的“旧”8.3 名称。
如果您愿意,您绝对可以使用 8.3 名称,只是不要向您的用户显示它,否则他们会(正确地)混淆。 或者只是使用适当的现代 API 来获取真实姓名。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.