利用C++獲取某一資料夾下的所有檔名,並獲取不帶字尾的檔名字
阿新 • • 發佈:2018-12-01
來源:https://www.cnblogs.com/fnlingnzb-learner/p/6424563.html
那麼到底如何查詢檔案呢?我們需要一個結構體和幾個大家可能不太熟悉的函式。這些函式和結構體在<io.h>的標頭檔案中,
結構體為struct _finddata_t ,函式為_findfirst、_findnext和_fineclose。
_finddata_t 結構體:儲存檔案各種資訊
unsigned atrrib:檔案屬性的儲存位置。它儲存一個unsigned單元,用於表示檔案的屬性。檔案屬性是用位表示的,主要有以下一些用無符號整數(2的幾次冪)定義的巨集:
_A_ARCH(存檔)、_A_HIDDEN(隱藏)、_A_NORMAL(正常)、_A_RDONLY(只讀)、_A_SUBDIR(資料夾)
這些都是在<io.h>中定義的巨集,可以直接使用,而本身的意義其實是一個無符號整型(只不過這個整型應該是2的幾次冪,從而保證只有一位為1,而其他位為0)。既然是位表示,那麼當一個檔案有多個屬性時,它往往是通過位或的方式,來得到幾個屬性的綜合。例如只讀+隱藏+系統屬性,應該為:_A_HIDDEN | _A_RDONLY | _A_SYSTEM 。
time_t time_create:這裡的time_t是一個變數型別(長整型?相當於long int?),用來儲存時間的,我們暫時不用理它,只要知道,這個time_create變數是用來儲存檔案建立時間的就可以了
time_t time_access:檔案最後一次被訪問的時間。
time_t time_write:檔案最後一次被修改的時間。
_fsize_t size:檔案的大小。這裡的_fsize_t應該可以相當於unsigned整型,表示檔案的位元組數。
char name[_MAX_FNAME]:檔案的檔名。這裡的_MAX_FNAME是一個常量巨集,它在<stdlib.h>標頭檔案中被定義,表示的是檔名的最大長度。
以此,我們可以推測出,struct _finddata_t ,大概的定義如下:
struct _finddata_t { unsigned attrib; time_t time_create; // -1 for FAT file systems time_t time_access; time_t time_write; _fsize_t size; char name[_MAX_FNAME]; };
函式:
- long _findfirst( char *filespec, struct _finddata_t *fileinfo );
返回值:如果查詢成功的話,將返回一個long型的唯一的查詢用的控制代碼(就是一個唯一編號)。這個控制代碼將在_findnext函式中被使用。若失敗,則返回-1。
filespec:標明檔案的字串,可支援萬用字元。比如:*.c,則表示當前資料夾下的所有後綴為C的檔案。
fileinfo :這裡就是用來存放檔案資訊的結構體的指標。這個結構體必須在呼叫此函式前宣告,不過不用初始化,只要分配了記憶體空間就可以了。函式成功後,函式會把找到的檔案的資訊放入這個結構體中。 - int _findnext( long handle, struct _finddata_t *fileinfo );
返回值:若成功返回0,否則返回-1。
handle:即由_findfirst函式返回回來的控制代碼。
fileinfo:檔案資訊結構體的指標。找到檔案後,函式將該檔案資訊放入此結構體中。 - int _findclose( long handle );
返回值:成功返回0,失敗返回-1。
handle :_findfirst函式返回回來的控制代碼。
函式實現:
獲取某一資料夾下的所有檔名
void getFiles(string path, vector<string>& files)
{
//檔案控制代碼:檔案的唯一標識
//long hFile = 0;//32位能跑動
intptr_t hFile = 0;//因為_findfirst和_findnext返回intptr_t而非long型
//定義儲存檔案資訊的結構體
struct _finddata_t fileinfo;
string p;
if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)//string轉化為c_str即C型別的字串
{
do
{
//如果是目錄,迭代之
//如果不是,加入列表
if ((fileinfo.attrib & _A_SUBDIR))//&:attrib和_A_SUBDIR做一次與運算,返回1則為_A_SUBDIR(資料夾)
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
getFiles(p.assign(path).append("\\").append(fileinfo.name), files);//遞迴
}
else
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name));
}
}
while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
只取檔名,去除字尾(應用於利用數字命名並需要對齊排序的檔案)
string removeSuffix(string fileName)
{
const char* full_name = fileName.c_str();
const char* mn_first = full_name;
int tmp = strlen(full_name);//長度不包含'/0'
const char* mn_last = full_name /*+ strlen(full_name)*/;
if (strrchr(full_name, '\\') != NULL)//去除路徑,只留檔名
mn_first = strrchr(full_name, '\\') + 1;
else if (strrchr(full_name, '/') != NULL)//去除linux下的檔案路徑
mn_first = strrchr(full_name, '/') + 1;
if (strrchr(full_name, '.') != NULL)
mn_last = strrchr(full_name, '.');//獲取.*字尾
if (mn_last < mn_first)//地址比較
mn_last = full_name + strlen(full_name);
fileName.assign(mn_first, mn_last);//引數10001.jpg和.jpg
return fileName;
}
註釋:
函式名稱: strrchr
函式原型:char *strrchr(const char *str, char c);
所屬庫: string.h
函式功能:查詢一個字元c在另一個字串str中末次出現的位置(也就是從str的右側開始查詢字元c首次出現的位置),並返回這個位置的地址。如果未能找到指定字元,那麼函式將返回NULL。使用這個地址返回從最後一個字元c到str末尾的字串。
對應於C++的find_last_of函式,不同點,返回位置索引。