You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 14:45:08