2

所以我希望能够自动重命名用户指定目录中的所有文件(我知道 c++ 不是执行此操作的最佳语言/工具)。

例如,一个目录当前包含数百个具有随机字符名称的文件,我希望将它们全部更改为

8 月 1 日、8 月 2 日、8 月 3 日等

编码

用户指定这样的目录

std::string directory;

std::cout << "Enter directory: ";
std::cin >> directory;

目录是这样打开的(使用dirent.h

DIR* pdir = NULL;
struct dirent* pent = NULL;
const char* DIRECTORY;

// convert directory string to const char
DIRECTORY = directory.c_str();

pdir = opendir(DIRECTORY);

在此处重命名指定目录中的所有文件

int i = 1;
std::string s, oldname, newname;
const char* OLDNAME, * NEWNAME;

while (pent = readdir(pdir))
{
    // convert int i to str s
    std::stringstream out;
    out << i;
    s = out.str();

    oldname = pent->d_name;
    newname = "August " + s;

    OLDNAME = oldname.c_str();
    NEWNAME = newname.c_str();

    rename(OLDNAME, NEWNAME);

    i++;
}

一切正常,直到 while 循环似乎什么也没做,这就是我坚持的部分。

然而,奇怪的是,这个 while 循环旨在显示目录的内容(使用与非工作循环相同的逻辑和语法)完美地工作

while (pent = readdir (pdir))
{
    std::cout << pent->d_name << "\n";
}

Win7上使用MSVS2012


我想我会遇到的另一个问题是,在目录中,不同的文件具有不同的扩展名(这可能可以通过保存原始名称的最后 4 个字符并将其附加到新名称来解决,但不是当然,我们将不胜感激帮助)。

4

2 回答 2

3

使用<filesystem>,现在可以做类似以下的事情。我希望这可能对未来的读者有所帮助:

#include <iostream>
#include <string>
#include <filesystem>  //std::filesystem::path, std::filesystem::recursive_directory_iterator

std::string changeFileName(const std::string& currentFileName, const std::string& extension, int number)
{
   std::cout << "Current file name: " << currentFileName << "\n";

   // ....other logics regarding current filename

   const std::string newFileName{ "August - " + std::to_string(number) + extension};    
   std::cout << "File name after renaming: " << newFileName << "\n";
   return newFileName; // new file name
}

int main()
{
   const std::filesystem::path myPath = ".....full path....";
   const std::string extension{ ".txt" };
   int number{ 0 };
   // iterate through all the files in the directory
   for (const auto& dirEntry : std::filesystem::directory_iterator(myPath))
   {
      // if the file is meant for changing name!
      if (std::filesystem::is_regular_file(dirEntry) && dirEntry.path().extension() == extension)
      {
         const std::string currentFileName{ dirEntry.path().filename().string() };
         // following function is meant for the logic to provide the new file names in the directory
         // in your case it cout have been simply: "August - " + std::to_string(number++) + "extension"
         const std::string newFileName{ changeFileName(currentFileName, extension, number++) };
         try
         {
            std::filesystem::rename(myPath / currentFileName, myPath / newFileName);
         }
         catch (std::filesystem::filesystem_error const& error)  // catch the errors(if any)!
         {
            std::cout << error.code() << "\n" << error.what() << "\n";
         }
      }

   }
}
于 2020-02-16T10:51:08.303 回答
1

问题是这pent->d_name只是没有关联路径的文件名。因此,当您执行rename时,程序将oldname在当前目录中查找,并且由于该目录中不存在它,因此rename不会执行任何操作。要解决这个问题,您应该将路径附加到oldnameand newname,例如:

oldname = (std::string(DIRECTORY)+pent->d_name).c_str();
newname = (std::string(DIRECTORY)+"August " + s).c_str();
于 2014-12-07T23:49:57.330 回答