C++獲取檔名稱,去除字尾,排序,移動相關(VS版本和命令列即指令碼版本)
阿新 • • 發佈:2018-12-01
功能:
1. 獲取某一資料夾下的所有檔名
2.去除檔名字尾
3.將去除字尾的檔名轉為整形,並排序
4.將排序好的檔案分組,分別存入不同的資料夾
note:
1.用到了快速排序
2.利用檔案流實現檔案的移動,簡單易懂,比MoveFile函式好用
3.利用流實現string轉int(c++推薦)
VSb版本主程式:可直接在VS2015下執行
#include <iostream> #include <io.h> #include <xstring> #include <vector> #include <sstream> #include <fstream> #include <windows.h> #include <direct.h> using namespace std; void getFiles(string path, vector<string>& files); string removeSuffix(string fileName); int str2int(const string str); void quickSort(vector<int>& vec, int startIndex, int endIndex); int partition(vector<int>& vec, int startIndex, int endIndex); void mkdir(const vector<int> numFiles, const string dirPath); int main() { vector<string> files; const char* directory = "D:\\workspace\\20181112\\pic\\20171114_1456_A"; string dirPath = "D:\\workspace\\20181112\\pic\\20171114_1456_A"; getFiles(directory, files); //去除字尾,並轉為int vector<string> remFiles; vector<int> numFiles; int nSize = files.size(); for (int i = 0; i < nSize; i++) { string remFile = removeSuffix(files[i]); int num = str2int(remFile); remFiles.push_back(remFile); numFiles.push_back(num); } quickSort(numFiles, 0, numFiles.size() - 1); mkdir(numFiles, dirPath); cout << "Done!" << endl; return 0; } 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; } int str2int(const string str) { int tmp; stringstream stream(str); stream >> tmp; return tmp; } void quickSort(vector<int>& vecVec, int startIndex, int endIndex) { if (startIndex < endIndex) { int pivot = partition(vecVec, startIndex, endIndex); quickSort(vecVec, startIndex, pivot); quickSort(vecVec, pivot + 1, endIndex); } } int partition(vector<int>& vec, int startIndex, int endIndex) { int left = startIndex; int right = endIndex; int pivot = vec[startIndex]; while (left < right) { while (left < right && vec[right] >= pivot) right--; while (left < right && vec[left] <= pivot) left++; int tmp = vec[left]; vec[left] = vec[right]; vec[right] = tmp; } int tmp = vec[left]; vec[left] = pivot; vec[startIndex] = tmp; return left; } void mkdir(const vector<int> numFiles, const string dirPath) { vector<vector<int>> nameGroup; int nSize = numFiles.size(); vector<int> tmp; //分組 for (int i = 0;i < nSize - 1; i++) { int dif = numFiles[i + 1] - numFiles[i]; if (dif == 2) { tmp.push_back(numFiles[i]); } else { tmp.push_back(numFiles[i]); nameGroup.push_back(tmp); tmp.clear(); } } //處理邊界 tmp.push_back(numFiles.back()); nameGroup.push_back(tmp); //建立目錄並移動檔案 int nDir = nameGroup.size(); vector<string> strGroup; for (int i = 0; i < nDir; i++) { int n_1 = nameGroup[i].front(); int n_2 = nameGroup[i].back(); string str_1 = to_string(n_1); string str_2 = to_string(n_2); string strDir = dirPath + "\\" + str_1 + "-" + str_2; const char* dir = strDir.c_str(); _mkdir(dir); //檔案的移動 for (int j = 0; j < nameGroup[i].size(); j++) { string strFileName = dirPath + "\\" + to_string(nameGroup[i][j]) + ".jpg";//原始檔 string strFileDir = strDir +"\\"+ to_string(nameGroup[i][j]) + ".jpg";//目標檔案 const char* cN = strFileName.c_str(); const char* cD = dir; ifstream ifs(strFileName, ios_base::binary);//讀入流 if (!ifs.is_open()) { break; } ofstream ofs(strFileDir, ios_base::binary); ofs << ifs.rdbuf(); ifs.close(); if (remove(cN) != 0) { cout << "刪除失敗" << endl; break; } } cout << "第" << i << "組拷貝完成" << endl; } }
命令列版本:
將release版本的.exe程式拷貝到存放圖片的檔案目錄下,在shell下執行
./mkdir.exe
命令列下在VS除錯:
程式:只有main函式改變
int main(int argc,char* argv[]) { if (argc != 1) { cout << "引數應為1" << endl; cout << "False!" << endl; return 3; } vector<string> files; const char* directory = "./"; string dirPath = "./"; getFiles(directory, files); //去除字尾,並轉為int vector<string> remFiles; vector<int> numFiles; int nSize = files.size(); for (int i = 0; i < nSize; i++) { string remFile = removeSuffix(files[i]); int num = str2int(remFile); remFiles.push_back(remFile); numFiles.push_back(num); } quickSort(numFiles, 0, numFiles.size() - 1); mkdir(numFiles, dirPath); cout << "Done!" << endl; return 0; }