#include <iostream>
#include <string>
#include <windows.h>
#include <vector>
#include <iomanip>
#include <sstream>
using namespace std;
// 转换FILETIME到本地时间字符串
string FileTimeToString(const FILETIME& ft) {
SYSTEMTIME st;
FileTimeToSystemTime(&ft, &st);
char buffer[26];
sprintf_s(buffer, "%04d-%02d-%02d %02d:%02d:%02d",
st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond);
return string(buffer);
}
// 获取文件创建时间
FILETIME GetFileCreationTime(const string& filePath) {
HANDLE hFile = CreateFileA(filePath.c_str(), GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
FILETIME ftCreation = {0};
if (hFile != INVALID_HANDLE_VALUE) {
FILETIME ftAccess, ftWrite;
if (GetFileTime(hFile, &ftCreation, &ftAccess, &ftWrite)) {
// 时间获取成功
}
CloseHandle(hFile);
}
return ftCreation;
}
// 比较两个FILETIME(time1 >= time2 返回true)
bool CompareFileTime(const FILETIME& time1, const FILETIME& time2) {
return (::CompareFileTime(&time1, &time2) >= 0);
}
// 搜索符合条件的文件
vector<string> SearchFiles(const string& directory,
const string& fileType,
const FILETIME& startTime,
const FILETIME& endTime) {
vector<string> result;
string searchPath = directory + "\\*";
WIN32_FIND_DATAA findData;
HANDLE hFind = FindFirstFileA(searchPath.c_str(), &findData);
if (hFind != INVALID_HANDLE_VALUE) {
do {
// 跳过当前目录和上级目录
if (strcmp(findData.cFileName, ".") == 0 ||
strcmp(findData.cFileName, "..") == 0) {
continue;
}
// 构建完整路径
string fullPath = directory + "\\" + findData.cFileName;
// 处理目录递归搜索
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
vector<string> subFiles = SearchFiles(fullPath, fileType, startTime, endTime);
result.insert(result.end(), subFiles.begin(), subFiles.end());
continue;
}
// 检查文件类型
string fileName = findData.cFileName;
size_t dotPos = fileName.find_last_of('.');
string ext = (dotPos != string::npos) ?
fileName.substr(dotPos + 1) : "";
if (!fileType.empty() && _stricmp(ext.c_str(), fileType.c_str()) != 0) {
continue;
}
// 检查创建时间
FILETIME creationTime = findData.ftCreationTime;
if ((CompareFileTime(creationTime, startTime) ||
(startTime.dwHighDateTime == 0 && startTime.dwLowDateTime == 0)) &&
(CompareFileTime(endTime, creationTime) ||
(endTime.dwHighDateTime == 0 && endTime.dwLowDateTime == 0))) {
result.push_back(fullPath);
}
} while (FindNextFileA(hFind, &findData) != 0);
FindClose(hFind);
}
return result;
}
// 重命名文件
bool RenameFile(const string& oldPath, const string& newPath) {
if (MoveFileA(oldPath.c_str(), newPath.c_str())) {
cout << "成功: " << oldPath << " -> " << newPath << endl;
return true;
} else {
DWORD error = GetLastError();
cout << "错误: 重命名失败 - " << oldPath
<< " 错误码: " << error << endl;
return false;
}
}
// 转换用户输入的日期为FILETIME
FILETIME StringToFileTime(const string& dateStr) {
SYSTEMTIME st = {0};
if (dateStr.length() >= 10) {
sscanf_s(dateStr.c_str(), "%4d-%2d-%2d",
&st.wYear, &st.wMonth, &st.wDay);
FILETIME ft;
SystemTimeToFileTime(&st, &ft);
return ft;
}
// 返回0表示不限制时间
FILETIME zero = {0};
return zero;
}
int main() {
cout << "===== 文件搜索与重命名工具 (VS2008兼容版) =====" << endl;
// 设置搜索目录
string directory;
cout << "请输入搜索目录 (例如: C:\\MyFiles): ";
getline(cin, directory);
// 获取文件类型筛选条件
string fileType;
cout << "请输入文件类型 (如txt, jpg, 留空则不限制): ";
getline(cin, fileType);
// 获取时间范围
string startDate, endDate;
cout << "请输入开始日期 (格式: YYYY-MM-DD, 留空则不限制): ";
getline(cin, startDate);
cout << "请输入结束日期 (格式: YYYY-MM-DD, 留空则不限制): ";
getline(cin, endDate);
FILETIME startTime = StringToFileTime(startDate);
FILETIME endTime = StringToFileTime(endDate);
// 搜索文件
cout << "\n正在搜索文件..." << endl;
vector<string> files = SearchFiles(directory, fileType, startTime, endTime);
if (files.empty()) {
cout << "未找到符合条件的文件!" << endl;
system("pause");
return 0;
}
// 显示搜索结果
cout << "\n找到 " << files.size() << " 个文件:" << endl;
for (size_t i = 0; i < files.size(); i++) {
size_t pos = files[i].find_last_of("\\/");
string fileName = (pos != string::npos) ? files[i].substr(pos + 1) : files[i];
cout << "[" << setw(3) << i+1 << "] " << fileName << endl;
}
// 选择重命名模式
int renameMode;
cout << "\n请选择重命名模式:" << endl;
cout << "1. 添加前缀" << endl;
cout << "2. 添加后缀" << endl;
cout << "3. 替换文本" << endl;
cout << "4. 序列编号" << endl;
cout << "请输入选项 (1-4): ";
cin >> renameMode;
cin.ignore();
string prefix, suffix, oldText, newText;
int startNum = 1;
string format;
switch (renameMode) {
case 1:
cout << "请输入要添加的前缀: ";
getline(cin, prefix);
break;
case 2:
cout << "请输入要添加的后缀: ";
getline(cin, suffix);
break;
case 3:
cout << "请输入要替换的文本: ";
getline(cin, oldText);
cout << "请输入替换后的文本: ";
getline(cin, newText);
break;
case 4:
cout << "请输入起始编号: ";
cin >> startNum;
cin.ignore();
cout << "请输入格式字符串 (例如: file_%%03d): ";
getline(cin, format);
break;
default:
cout << "无效的选项!" << endl;
system("pause");
return 1;
}
// 执行重命名
int successCount = 0;
cout << "\n==== 开始重命名 ====" << endl;
for (size_t i = 0; i < files.size(); i++) {
string filePath = files[i];
size_t lastSlash = filePath.find_last_of("\\/");
size_t lastDot = filePath.find_last_of(".");
string path = (lastSlash != string::npos) ?
filePath.substr(0, lastSlash + 1) : "";
string fileName = (lastSlash != string::npos) ?
filePath.substr(lastSlash + 1) : filePath;
string name = (lastDot != string::npos && lastDot > lastSlash) ?
fileName.substr(0, lastDot - lastSlash - 1) : fileName;
string ext = (lastDot != string::npos && lastDot > lastSlash) ?
fileName.substr(lastDot) : "";
string newName;
if (renameMode == 1) {
newName = prefix + name + ext;
}
else if (renameMode == 2) {
newName = name + suffix + ext;
}
else if (renameMode == 3) {
// 替换文本
size_t pos = 0;
while ((pos = name.find(oldText, pos)) != string::npos) {
name.replace(pos, oldText.length(), newText);
pos += newText.length();
}
newName = name + ext;
}
else if (renameMode == 4) {
// 序列编号
char numBuffer[20];
sprintf_s(numBuffer, format.c_str(), startNum++);
newName = numBuffer + ext;
}
string newFilePath = path + newName;
if (RenameFile(filePath, newFilePath)) {
successCount++;
}
}
cout << "\n==== 重命名完成 ====" << endl;
cout << "成功重命名 " << successCount << " 个文件" << endl;
cout << "失败 " << files.size() - successCount << " 个" << endl;
system("pause");
return 0;
}运行后出现错误:TEST_file_Rename.exe 中的 0x7c812aeb 处未处理的异常: Microsoft C++ 异常: 内存位置 0x0012f740 处的 std::out_of_range。基于vs2008向我提供优化后的代码