C++中_finddata_t結構體儲存檔案資訊
最近除錯程式的時候需要處理大量txt檔案,這裡對於處理各種檔案的資訊做個筆記。
Struct _finddata_t結構體可以用來處理各種檔案的檔案資訊,使用該結構體需要新增標頭檔案io.h。
它的定義如下所示
struct _finddata_t
{
unsigned attrib;
time_t time_create;
time_t time_access;
time_t time_write;
_fsize_t size;
char name[_MAX_FNAME];
};
對於該結構體中的各個變數的定義如下所示:
unsigned attrib:無符號整形、位表示。它的作用是表示檔案的屬性,一般來說,檔案的屬性有如下幾種:
_A_ARCH(存檔)、 _A_HIDDEN(隱藏)、_A_NORMAL(正常)、_A_RDONLY(只讀)、_A_SUBDIR(資料夾)、_A_SYSTEM(系統)
time_t time_create:表示從1970年1月1日0時0分0秒到現在時刻的秒數。
time_t time_access:檔案最後一次被訪問的時間
time_t time_write:檔案最後一次被修改的時間
_fsize_t size:檔案的大小。
char name[_MAX_FNAME]:檔案的檔名,這裡的_MAX_FNAME是一個常量巨集,它在標頭檔案中被定義,表示的是檔名的最大長度。
為了使用這個結構體將檔案的資訊儲存到該結構體的記憶體空間,需要搭配使用_findfirst()、_findnext()、_findclose()
long _findfirst( char *filespec, struct _finddata_t *fileinfo );
返回值:如果查詢成功,那麼就返回一個long型的唯一查詢用的控制代碼。這個控制代碼會在_findnext函式中被使用。失敗的話就會返回0.
引數:filespec:標明檔案的字串。例如:*.c
fileinfo:這裡就是用來存放檔案資訊的結構體的指標。函式成功後,函式會把找到的檔案的資訊放入這個結構體所分配的記憶體空間中。
int _findnext( long handle, struct _finddata_t *fileinfo );
返回值:若成功返回0,否則返回-1。
引數:handle:即由_findfirst函式返回回來的控制代碼。
int _findclose( long handle );
返回值:成功返回0,失敗返回-1。
下面介紹一下C++裡面的控制代碼,為了區分控制代碼和指標。分別介紹一下:
指標:指標通俗來著就是地址,他是記憶體的編號,通過指標我們可以直接對記憶體進行操作,只要地址不變,我們每次操作的物理位置是絕對不變的。
控制代碼:一般是指向系統的資源的位置,可以說也是地址。但是這些資源的位置真的不變,我們都知道window支援虛擬記憶體的技術,同一時間內可能有些資源被換出記憶體,一些被換回來,這就是說同一資源在系統的不同時刻,他在記憶體的物理位置是不確定的,那麼window是如何解決這個問題呢,就是通過控制代碼來處理資源的物理位置不斷變化的這個問題的。window會在物理位置固定的區域儲存一張對應表,表中記錄了所有的資源實時地址,控制代碼其實沒有直接指向資源的實體地址,而是指向了這個對應表中的一項,這樣無論資源怎樣的換進換出,通過控制代碼都可以找到他的實時位置。
以下為解決工程問題所寫的小測試程式:
#include <iostream>
#include <io.h>
#include <Windows.h>
#include <vector>
#include <string>
using namespace std;
#define ADDR "C://Users//CiCi//Desktop//8.7//*.txt"
const char *SearchAddr = ADDR;
int main()
{
long Handle;
struct _finddata_t FileInfo;
vector<string>name;
vector<string>direction;
vector<string>last_t;
vector<int>id;
vector<int>direction_2;
Handle = _findfirst(SearchAddr, &FileInfo);
name.push_back(FileInfo.name);
while (!_findnext(Handle, &FileInfo))
{
name.push_back(FileInfo.name);
}
for (auto it = name.begin(); it != name.end(); it++)
{
/*cout << *it << endl;*/
string str = *it;
direction.push_back(str.substr(21, 1));
last_t.push_back(str.substr(0, 6));
}
for (auto it = direction.begin(); it != (direction.end()-3); it = it + 3)
{
string a = *it;
string b = *(it + 3);
auto c = a.compare(b);
direction_2.push_back(c);
}
for (auto it = last_t.begin(); it !=(last_t.end() - 3); it = it + 3)
{
string a = *it;
string b = *(it + 3);
auto c = a.compare(b);
/*cout << c << endl;*/
id.push_back(c);
}
for (auto it = id.begin(); it != id.end(); it++)
{
if (direction_2.at(it - id.begin())== 0 && id.at(it - id.begin())==0)
{
cout << name.at(3*(it - id.begin())) << endl;
}
}
_findclose(Handle);
return 0;
}
這裡有幾個注意的地方:
1.使用_findfirst函式之後,要立刻把檔名存入vector容器中去,不然接下來呼叫_findnext函式會導致缺少第一個檔案。
2.這裡使用了string的一個substr函式,函式結構為str.substr(m,n)。其中,str為string型變數的變數名,m為字串的第m個字元,n為從第m個字元起的個數。
3.比較兩個string物件是否相等,這裡用compare函式,函式結構為s1.compare(s2),如果兩個string物件相等的話,就會返回0;