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