Dev C++环境下C++ rename函数批量重命名总返回Permission denied报错
核心报错原因
你遇到的Permission denied错误90%以上是因为没有过滤.和..两个特殊目录项,代码尝试对系统目录执行重命名操作被操作系统拦截。其余错误是路径拼接错误、输入残留换行引发的次生问题。
代码存在的所有问题
- 未过滤
readdir返回的.(当前目录)、..(上级目录)特殊项,直接对这两个系统目录执行重命名直接触发权限报错 - 仅向
rename函数传入纯文件名,没有拼接目标目录前缀,程序只会在自身运行的工作目录查找文件,路径不匹配引发报错 cin >>读取输入后缓冲区残留换行符,导致第一次getline读取到空文件名,引发重命名错误- 未过滤非目标格式文件,会误操作目录内的其他文件、子目录
修复后代码
#include <iostream> #include <dirent.h> #include <string> #include <fstream> #include <cstring> #include <memory.h> using namespace std; int main(int argc, char *argv[]){ string directory, path; cout<<"Jump to directory : "; cin>>directory; cout<<"Give path where to read out : "; cin>>path; // 清除cin残留的换行符,避免后续getline读空 cin.ignore(); // 统一目录路径结尾的分隔符 if (directory.back() != '/' && directory.back() != '\\') { directory += "/"; } ifstream file; file.open(path.c_str(), ios::in); if (!file) { cout << endl << "Error occured while opening " << path << "..."<<endl; system("pause"); return 1; } DIR *dirDirectory; struct dirent *dirreadDirectory; const string datatype = ".mkv"; if((dirDirectory = opendir(directory.c_str())) != NULL) { while ((dirreadDirectory = readdir(dirDirectory)) != NULL) { // 跳过特殊目录项 if (strcmp(dirreadDirectory->d_name, ".") == 0 || strcmp(dirreadDirectory->d_name, "..") == 0) { continue; } // 可选:跳过非mkv后缀的文件 string oldName = dirreadDirectory->d_name; if (oldName.size() < datatype.size() || oldName.substr(oldName.size() - datatype.size()) != datatype) { continue; } string getNewName; if (!getline(file, getNewName) || getNewName.empty()) { cout << "No available new name for file: " << oldName << endl; continue; } // 拼接完整路径 string oldFullPath = directory + oldName; string newFullPath = directory + getNewName + datatype; if (rename(oldFullPath.c_str(), newFullPath.c_str()) != 0){ perror(("Error renaming file: " + oldName).c_str()); }else{ cout<<"Successfully renamed: "<<oldName <<" -> "<<getNewName + datatype<<endl; } } closedir(dirDirectory); file.close(); } else{ perror("could not open directory"); } system("pause"); return 0; }
额外注意事项
- 确认TXT文件里的新名字数量和目录里的mkv文件数量一致,顺序对应
- 测试时可以先把rename调用替换成cout打印两个路径,确认路径完全正确后再执行实际重命名操作
内容的提问来源于stack exchange,提问作者alessio
相关产品推荐
相关产品推荐

