【C++】ディレクトリを削除する方法 [remove_all] or [rmdir]

C++界隈で約20年ダメプログラマをやっているまさじぃです。

今回は、C++でディレクトリを削除する方法。

C++17以降では、std::filesystem::remove_allを使用、C++17以前ではrmdirを使用して削除します。

std::filesystem::remove_allを使用して削除する

C++17から導入されているstd::filesystem::remove_allを使用して削除する方法です。

#include <cstdio>
#include <iostream>
#include <filesystem>

int main() {
  std::string dir_path = "directory";

  try {
    if (std::filesystem::exists(dir_path)) {
      std::filesystem::remove_all(dir_path);  // ディレクトリ削除
      std::cout << "Deleted!!" << std::endl;
    } else {
      // ディレクトリ無し
      std::cout << "Directroy does not exist!!" << std::endl;
    }
  } catch (const std::filesystem::filesystem_error& e) {
    // エラー発生
    std::cout << "Error!! " << e.what() << std::endl;
  }

  return 1;
}

std::filesystem::remove_allの利点はディレクトリの中身もすべて削除することができることです。

C++17以降では、std::filesystem::remove_allを使用することで、ディレクトリ内のファイル有無を気にすること無くディレクトリ削除が行えます。

rmdirを使用して削除する

色々な制約でC++17以降を使用できない場合は、rmdirを使用して削除します。

ただし、空のディレクトリに限ります。

#include <iostream>
#include <unistd.h>

int main() {
  const char* path = "directory";

  if (rmdir(path) == 0) {
    std::cout << "Deleted!!  " << path << std::endl;
  } else {
    std::cout << "Error!!" << std::endl;
  }

  return 0;
}

ディレクトリにファイルなどが格納されている場合は、rmdirでは削除できないので以下のように存在するファイルを再帰的に削除してから最後にディレクトリを削除します。

rmdirとstd::removeを使ってディレクトリを削除する関数

std::removeを使用してディレクトリ内のファイルを削除し、ディレクトリが空になったらrmdirでディレクトリを削除する関数です。

ディレクトリ内にディレクトリが存在する可能性もあるので、再帰的に動作します。

#include <iostream>
#include <cstdio>
#include <string>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>

bool removeDirectory(const std::string& path) {
  DIR* dir = opendir(path.c_str());
  if (!dir) {
    std::cout << "Directory Open Error!!" << std::endl;
    return false;
  }

  struct dirent* entry;
  while ((entry = readdir(dir)) != nullptr) {
    std::string name = entry->d_name;
    if (name == "." || name == "..") continue;  // "." と ".." はスキップ

    std::string full_path = path + "/" + name;

    struct stat st;
    if (stat(full_path.c_str(), &st) == 0) {
      if (S_ISDIR(st.st_mode)) {
        // 再帰的にサブディレクトリを削除
        if (!removeDirectory(full_path)) {
          closedir(dir);
          return false;
        }
      } else {
          // ファイルを削除
          if (std::remove(full_path.c_str()) != 0) {
            std::cout << "File Remove Error!! : " << full_path << std::endl;
            closedir(dir);
            return false;
          }
      }
    }
  }
  closedir(dir);

  // 最後にディレクトリ自体を削除
  if (rmdir(path.c_str()) != 0) {
    std::cout << "Directory Remove Error!! : " << path << std::endl;
    return false;
  }

  return true;
}

int main() {
  std::string dirPath = "directory";
  if (removeDirectory(dirPath)) {
    std::cout << "Success!! dirctory : " << dirPath << std::endl;
  } else {
    std::cout << "Error!! directory : " << dirPath << std::endl;
  }

  return 0;
}

opendirでディレクトリを開いて、readdirでディレクトリ内の情報を読み込んでいます。

stat()で対象のパスの情報を取得してS_ISDIR()でディレクトリかどうかの判定を行って、ディレクトリなら再帰的にremoveDirectory()を呼び出し、ファイルならstd::removeで削除しています。

削除対象ディレクトリ内の全てのファイルを削除が完了したら、最後にディレクトリを削除して完了です。

C++でディレクトリ削除する方法 まとめ

C++でディレクトリを削除する方法は、std::filesystem::remove_allrmdirがあります。

C++17以降を使用できる場合は、迷わずstd::filesystem::remove_allを使用しましょう。ディレクトリ内にファイルが存在する場合でも簡単に削除することが可能です

C++17以降を使用できない場合は、rmdirを使用します。

ただし、rmdir削除できるのは空のディレクトリのみなので、ディレクトリ内にファイルが存在する場合には削除することができません。

その場合は、opendirstd::removeなどを使用して再帰的にディレクトリ内ファイルを削除する関数を作成することでディレクトリ削除を実現します。

スポンサーリンク

  • この記事を書いた人

まさじぃ

ダメプログラマ歴20年です。 プログラミング関連の事や、 自分で使って良かったもの等の紹介をメインにやっています。

-プログラミング
-