今天我遇到了這樣一個任務:要求編寫一個程序,統計和這個程序在同一目錄下(及其子目錄)所有文件的單詞數。統計單詞數十分倒不是太難,倒是找出同一目錄下的所有文件,是我從來沒有接觸過的。仔細分析,這個問題其實包含兩個小問題:
1. 如何獲取當前程序所在文件夾的路徑
2. 如何給定一個路徑,遞歸地找到其中(包括子目錄)所有文件的文件名(相對路徑)
那我們就依次解決這兩個問題。
.
.
1. 如何獲取當前程序所在文件夾的路徑
.
.
解決這個問題只需要一個簡單的函數即可(需要包含一個輸入輸出庫):
#include <io.h>
char *getcwd( char *buffer, int maxlen );
這個函數能夠獲取當前的工作目錄,具體來說,它會將當前工作目錄的絕對路徑復制到參數buffer所指的內存空間中,參數maxlen為buffer的空間大小。
.
我們可以寫一個程序來測試一下。
#include<iostream>
#include<io.h>
using namespace std;
#define MAX_PATH 80
int main()
{
char buffer[MAX_PATH];
getcwd(buffer, MAX_PATH);
cout << buffer << endl;
return 0;
}
.
運行成功!
.
.
.
2. 如何給定一個路徑,遞歸地找到其中(包括子目錄)所有文件的文件名(相對路徑)
.
.
這里我使用了網上現成的代碼,先附上鏈接。
.
這里,他定義了一個函數(需要包含一個向量庫,當然,還有我們在上一個問題里需要使用的輸入輸出庫)
#include <io.h>
#include<vector>
void getFiles(string path, vector<string>& files);
它的用處是,給定一個文件目錄path,然后找到其中所有(包括其子目錄里)的文件,將文件名放入files中,files是一個字符串向量的引用類型。
.
具體的函數內容是這樣的:
void getFiles( string path, vector<string>& files )
{
//文件句柄
long hFile = 0;
//文件信息
struct _finddata_t fileinfo;
string p;
if((hFile = _findfirst(p.assign(path).append("\\*").c_str(),&fileinfo)) != -1)
{
do
{
//如果是目錄,迭代之
//如果不是,加入列表
if((fileinfo.attrib & _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);
}
}
.
下面給出一個運用這個函數的例子:
#include<iostream>
#include<vector>
#include<io.h>
using namespace std;
#define MAX_PATH 80
void getFiles( string path, vector<string>& files );
int main()
{
vector<string> files;
char * filePath = "C:\\Users\\Star\\Desktop\\SoftTest";
////獲取該路徑下的所有文件
getFiles(filePath, files);
char str[30];
int size = files.size();
for (int i = 0;i < size;i++)
{
cout<<files[i].c_str()<<endl;
}
return 0;
}
運行成功!
.
.
.
3. 組合以后的完整代碼
.
#include<iostream>
#include<vector>
#include<io.h>
using namespace std;
#define MAX_PATH 80
void getFiles( string path, vector<string>& files );
int main()
{
vector<string> files;
char buffer[MAX_PATH];
getcwd(buffer, MAX_PATH);
char * filePath = buffer;
////獲取該路徑下的所有文件
getFiles(filePath, files );
char str[30];
int size = files.size();
for (int i = 0;i < size;i++)
{
cout<<files[i].c_str()<<endl;
}
return 0;
}
void getFiles( string path, vector<string>& files )
{
//文件句柄
long hFile = 0;
//文件信息
struct _finddata_t fileinfo;
string p;
if((hFile = _findfirst(p.assign(path).append("\\*").c_str(),&fileinfo)) != -1)
{
do
{
//如果是目錄,迭代之
//如果不是,加入列表
if((fileinfo.attrib & _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);
}
}
.
這段代碼的運行結果和上面的運行結果相同,我就不給出運行結果了。
.
.
.
4.返回相對路徑
.
之前的那種方法很好,不過唯一的缺點是,函數返回的都是絕對路徑,如果想要改成相對路徑,該怎么辦呢?
.
.
我將代碼進行了修改,具體做法是在getFile()函數中加入了一個path2參數,改進后的代碼如下:
.
#include<iostream>
#include<vector>
#include<io.h>
using namespace std;
#define MAX_PATH 80
void getFiles( string path, string path2, vector<string>& files );
int main(){
vector<string> files;
char buffer[MAX_PATH];
getcwd(buffer, MAX_PATH);
string filePath;
filePath.assign(buffer).append("\\");
////獲取該路徑下的所有文件
getFiles(filePath,"", files );
char str[30];
int size = files.size();
for (int i = 0;i < size;i++)
{
cout<<files[i].c_str()<<endl;
}
return 0;
}
void getFiles( string path, string path2, vector<string>& files )
{
//文件句柄
long hFile = 0;
//文件信息
struct _finddata_t fileinfo;
string p,p2;
if((hFile = _findfirst(p.assign(path).append(path2).append("*").c_str(),&fileinfo)) != -1)
{
do
{
//如果是目錄,迭代之
//如果不是,加入列表
if((fileinfo.attrib & _A_SUBDIR))
{
if(strcmp(fileinfo.name,".") != 0 && strcmp(fileinfo.name,"..") != 0)
getFiles( p.assign(path).append("\\"),p2.assign(fileinfo.name).append("\\"), files );
}
else
{
files.push_back(p.assign(path2).append(fileinfo.name) ); //這一行可以給出相對路徑
//files.push_back(p.assign(fileinfo.name) ); //這一行可以給出文件名
}
}while(_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
.
運行結果:
成功地給出了相對路徑!!
.
.
也可以給出文件名:
.
.
.