簡體   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