最近接到一个小任务,需要对150人的文档进行分类汇总,每个人有两个文件。最终需要将每个人的两个文件新建一个文件夹进行单独存放。就尝试用C++代码批量处理了一波,记录如下:
一、问题分析:
1、由于每个文件是每个学生提交,因此最终的文档呈现各种不规范的命名方式。
2、有的学生存在学号写错的情况。
二、解决想法及流程:
1、批量修改文件名,统一化命名方式;
2、程序自动检查同一个人的两个文件名中的学号是否一致,抛出信息,手动核查;
3、自动新建个人文件夹,并将个人的两个文件移动到该文件下;
4、反向校验,将归档的个人信息打印,并在EXCEL中与信息汇总表进行差错比较;
三、代码部分
1、批量修改文件名:
#include <iostream>
#include <io.h>
#include <string>
#include <vector>
using namespace std;
void getFiles(const std::string & path, std::vector<std::string> & files)
{
//文件句柄
intptr_t hFile = 0;
//文件信息,_finddata_t需要io.h头文件
struct _finddata_t fileinfo;
std::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(fileinfo.name);
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
int main()
{
//用来存储文件名
vector<std::string> filenames;
string path = "C:\\Users\\xxx\\Desktop\\2020.6.22归档\\文档汇总\\L";
getFiles(path, filenames);
int i = 0;
for (auto file : filenames)
{
string studetNum, studentName;
for (int i = 0; i < file.size();) {
if (!(file[i] < 0) && isdigit(file[i]))
while (!(file[i] < 0) && isdigit(file[i])) {
studetNum.push_back(file[i]);
i++;
}
else if (file[i] < 0) {
int begin = i, num = 0;
while (file[i] < 0) {
num++; i++;
}
studentName = file.substr(begin, num);
}
else if (file[i] == '.') break;
else i++;
}
string newPath = path + "\\L+" + studetNum + " " + studentName + ".pdf";
string oldName = path + "\\" + file;
int result = rename(oldName.c_str(), newPath.c_str());
if (!(result == 0))
cout << "***Failed file name***" << oldName << endl;
//cout << oldName << " ==> " << newPath << endl;
}
return 0;
}
2、信息核对及文件移动
#include <iostream>
#include <direct.h>
#include <io.h>
#include <string>
#include <vector>
using namespace std;
void getFiles(const std::string & path, std::vector<std::string> & files)
{
//文件句柄
intptr_t hFile = 0;
//文件信息,_finddata_t需要io.h头文件
struct _finddata_t fileinfo;
std::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(fileinfo.name);
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
string getSubName(string& s) {
int begin = 0, end = 0;
while (s[begin++] != '+');
end = begin - 1;
while (s[end++] != '.');
string subName = s.substr(begin, end - begin - 1);
return subName;
}
int main()
{
//用来存储文件名
vector<std::string> filenames1;
vector<std::string> filenames2;
string basePath = "C:\\Users\\xxx\\Desktop\\2020.6.22总归档\\文档汇总";
string path1 = basePath + "\\K";
string path2 = basePath + "\\L";
getFiles(path1, filenames1);
getFiles(path2, filenames2);
for (int i = 0; i < filenames1.size();i++) {
string subName1 = getSubName(filenames1[i]);
string subName2 = getSubName(filenames2[i]);
if (subName1 != subName2) {
cout << "There is an error: " << endl;
cout << subName1 << " " << subName2;
}
string prefix = basePath + "\\" + subName1;
if (_access(prefix.c_str(), 0) == -1) //如果文件夹不存在
_mkdir(prefix.c_str()); //则创建
string oldName1 = path1 + "\\" + filenames1[i];
string newName1 = basePath + "\\" + subName1 + "\\" + filenames1[i];
string oldName2 = path2 + "\\" + filenames2[i];
string newName2 = basePath + "\\" + subName2 + "\\" + filenames2[i];
int result1 = rename(oldName1.c_str(), newName1.c_str());
int result2 = rename(oldName2.c_str(), newName2.c_str());
if(result1!=0|| result2 != 0)
cout << "***Failed file name***" << oldName1 << endl;
}
return 0;
}
3、EXCEL的反向检测
可能用到的几个方法:
1、单个数据表的拆分:https://zhidao.baidu.com/question/437159507167340284.html
2、核对两列数据是否存在差异:https://baijiahao.baidu.com/sid=1633587400784135995&wfr=spider&for=pc