繁体   English   中英

如何在Windows上的C/C++中读取包含'œ'作为字符的文件名

[英]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

您可以使用FindFirstFileWFindNextFileW作为支持 UTF16 字符串的平台 API。 但是,使用 std::filesystem 几乎没有理由这样做(至少对于您的用例而言)。

如果您使用 C,请直接使用操作系统函数,特别是FindFirstFileWFindNextFileW 请注意末尾的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM