C++获取文件的名称,去除文件的后缀,文件名的排序,文件的移动(VS版本和命令行即脚本版本)

功能:
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;
}

 

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值