C++でディレクトリ作成をマスターする5つの方法

C++でのディレクトリ作成を解説する記事のサムネイルC++
この記事は約19分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

この記事では、C++を用いてディレクトリを作成する方法を、初心者から上級者までが理解しやすい形で詳細に解説していきます。

ディレクトリ操作はファイルシステムを扱う上で非常に重要な部分を占め、C++におけるディレクトリの作成と管理方法は多くのアプリケーション開発において役立ちます。

この記事を通して、C++でのディレクトリ操作に関する基本的な知識から応用技術までを身につけることができます。

●C++とは

C++は、システムプログラミングやアプリケーション開発、ゲーム開発など、幅広い用途に使用される汎用プログラミング言語です。

C言語をベースに開発され、オブジェクト指向機能を備えた高性能な言語であり、効率的な処理能力と豊富なライブラリを持つことから、多くのプログラマーにとって不可欠なスキルとなっています。

○C++の基本的な特徴

C++は強力な型付けを特徴としており、これにより変数の型を厳密に管理し、エラーを早期に検出してプログラムの安全性を高めることができます。

また、オブジェクト指向プログラミングに対応しており、クラスとオブジェクトを用いてデータと操作をカプセル化することが可能です。

これは大規模なプログラム開発を容易にします。

さらに、手続き型プログラミングやオブジェクト指向プログラミング、汎用プログラミングなど複数のプログラミングスタイルをサポートしている点もC++の大きな特徴です。

そして、標準テンプレートライブラリ(STL)を含む豊富なライブラリが用意されており、これにより効率的なプログラミングが可能になります。

これらの特徴により、C++は多様なプログラミングニーズに応える強力な言語として広く使われています。

●C++でディレクトリを作成する方法

C++でディレクトリを作成するには、標準ライブラリのファイルシステム関連の機能を利用します。

ファイルシステムライブラリは、ファイルやディレクトリの操作を行うための便利なツールを提供しており、C++17以降の標準で利用可能です。

ディレクトリを作成する基本的なプロセスは、指定したパスにディレクトリが存在しない場合に新しいディレクトリを作成することです。

この操作を行うには、まずC++のプログラムにファイルシステムライブラリをインクルードする必要があります。

○準備(C++とファイルシステムライブラリ)

ファイルシステムライブラリを使用するには、プログラムの冒頭で次のようにヘッダをインクルードします。

#include <filesystem>
namespace fs = std::filesystem;

このコードにより、std::filesystem 名前空間を fs という別名で使用できるようになります。

これにより、ファイルシステムに関連するさまざまな操作が簡単に行えるようになります。

○サンプルコード1:基本的なディレクトリ作成

基本的なディレクトリ作成のためのコードは下記のようになります。

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int main() {
    fs::path dir = "example_dir"; // 作成するディレクトリのパス

    // ディレクトリが存在しない場合に作成
    if (!fs::exists(dir)) {
        fs::create_directory(dir);
        std::cout << "ディレクトリを作成しました: " << dir << std::endl;
    } else {
        std::cout << "ディレクトリは既に存在します: " << dir << std::endl;
    }

    return 0;
}

このコードでは、example_dir という名前のディレクトリを作成しています。

fs::path を使用してディレクトリのパスを指定し、fs::exists でそのディレクトリが既に存在するかどうかを確認しています。

存在しない場合には fs::create_directory でディレクトリを作成し、結果をコンソールに出力しています。

○サンプルコード2:ディレクトリ作成のエラーハンドリング

ディレクトリ作成時には、様々なエラーが発生する可能性があります。

たとえば、指定したパスにアクセス権限がない場合や、パスが不正な形式である場合などです。

これらのエラーを適切に処理するためには、例外処理を用いることが一般的です。

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int main() {
    fs::path dir = "example_dir";

    try {
        // ディレクトリ作成の試み
        if (!fs::exists(dir) && fs::create_directory(dir)) {
            std::cout << "ディレクトリを作成しました: " << dir << std::endl;
        } else {
            std::cout << "ディレクトリは既に存在するか、作成できませんでした。" << std::endl;
        }
    } catch (const fs::filesystem_error& e) {
        std::cerr << "エラー: " << e.what() << std

::endl;
    }

    return 0;
}

このコードでは、try-catch ブロックを用いてディレクトリ作成時の例外を捕捉しています。

fs::filesystem_error はファイルシステム操作中に発生する可能性のある例外を表し、エラーメッセージを含む情報を提供します。

このようにエラーハンドリングを行うことで、プログラムの堅牢性を高めることができます。

●ディレクトリ操作の応用例

C++におけるディレクトリ操作は基本的な作成、読み込み、削除だけでなく、より複雑な操作も可能です。

ここでは、サブディレクトリの作成、ディレクトリの存在確認、そしてディレクトリの削除という3つの応用例を紹介します。

これらの操作は、ファイルシステムの管理やデータの整理に非常に役立ちます。

○サンプルコード3:サブディレクトリの作成

サブディレクトリを作成することで、ファイルシステム内のデータをより整理しやすくなります。

下記のコードは、親ディレクトリ内に新しいサブディレクトリを作成する方法を表しています。

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int main() {
    fs::path parentDir = "example_dir";
    fs::path subDir = parentDir / "sub_dir"; // サブディレクトリのパス

    if (!fs::exists(subDir)) {
        fs::create_directories(subDir); // サブディレクトリを作成
        std::cout << "サブディレクトリを作成しました: " << subDir << std::endl;
    } else {
        std::cout << "サブディレクトリは既に存在します: " << subDir << std::endl;
    }

    return 0;
}

このコードでは、fs::path オブジェクトを使って親ディレクトリとサブディレクトリのパスを定義しています。

fs::create_directories 関数は、必要に応じて親ディレクトリも含めてディレクトリを作成します。

○サンプルコード4:ディレクトリの存在確認

プログラム内でディレクトリが存在するかどうかを確認することは、多くの場面で重要です。

下記のコードは、特定のディレクトリが存在するかどうかを確認する方法を表しています。

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int main() {
    fs::path dir = "example_dir";

    if (fs::exists(dir)) {
        std::cout << "ディレクトリが存在します: " << dir << std::endl;
    } else {
        std::cout << "ディレクトリが存在しません: " << dir << std::endl;
    }

    return 0;
}

このコードでは、fs::exists 関数を用いてディレクトリの存在を確認しています。

存在を確認した後の処理は、その結果に応じて変更することができます。

○サンプルコード5:ディレクトリの削除

不要になったディレクトリを削除する能力も、ファイルシステム管理において重要です。

下記のコードは、特定のディレクトリを削除する方法を表しています。

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int main() {
    fs::path dir = "example_dir";

    if (fs::exists(dir)) {
        fs::remove(dir); // ディレクトリを削除
        std::cout << "ディレクトリを削除しました: " << dir << std::endl;
    } else {
        std::cout << "削除するディレクトリが存在しません: " << dir << std::endl;
    }

    return 0;
}

このコードでは、fs::remove 関数を用いてディレクトリを削除しています。

ディレクトリの存在を確認した上で削除処理を行うことで、誤って重要なデータを失うリスクを避けることができます。

●ディレクトリ操作の応用例

C++におけるディレクトリ操作は基本的な作成、読み込み、削除だけでなく、より複雑な操作も可能です。

ここでは、サブディレクトリの作成、ディレクトリの存在確認、そしてディレクトリの削除という3つの応用例を紹介します。

これらの操作は、ファイルシステムの管理やデータの整理に非常に役立ちます。

○サンプルコード3:サブディレクトリの作成

サブディレクトリを作成することで、ファイルシステム内のデータをより整理しやすくなります。

下記のコードは、親ディレクトリ内に新しいサブディレクトリを作成する方法を表しています。

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int main() {
    fs::path parentDir = "example_dir";
    fs::path subDir = parentDir / "sub_dir"; // サブディレクトリのパス

    if (!fs::exists(subDir)) {
        fs::create_directories(subDir); // サブディレクトリを作成
        std::cout << "サブディレクトリを作成しました: " << subDir << std::endl;
    } else {
        std::cout << "サブディレクトリは既に存在します: " << subDir << std::endl;
    }

    return 0;
}

このコードでは、fs::path オブジェクトを使って親ディレクトリとサブディレクトリのパスを定義しています。

fs::create_directories 関数は、必要に応じて親ディレクトリも含めてディレクトリを作成します。

○サンプルコード4:ディレクトリの存在確認

プログラム内でディレクトリが存在するかどうかを確認することは、多くの場面で重要です。

下記のコードは、特定のディレクトリが存在するかどうかを確認する方法を表しています。

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int main() {
    fs::path dir = "example_dir";

    if (fs::exists(dir)) {
        std::cout << "ディレクトリが存在します: " << dir << std::endl;
    } else {
        std::cout << "ディレクトリが存在しません: " << dir << std::endl;
    }

    return 0;
}

このコードでは、fs::exists 関数を用いてディレクトリの存在を確認しています。

存在を確認した後の処理は、その結果に応じて変更することができます。

○サンプルコード5:ディレクトリの削除

不要になったディレクトリを削除する能力も、ファイルシステム管理において重要です。

下記のコードは、特定のディレクトリを削除する方法を表しています。

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int main() {
    fs::path dir = "example_dir";

    if (fs::exists(dir)) {
        fs::remove(dir); // ディレクトリを削除
        std::cout << "ディレクトリを削除しました: " << dir << std::endl;
    } else {
        std::cout << "削除するディレクトリが存在しません: " << dir << std::endl;
    }

    return 0;
}

このコードでは、fs::remove 関数を用いてディレクトリを削除しています。

ディレクトリの存在を確認した上で削除処理を行うことで、誤って重要なデータを失うリスクを避けることができます。

●ディレクトリ操作の詳細な使い方

C++でのディレクトリ操作は、単にファイルやフォルダを作成・削除するだけでなく、より詳細な操作が可能です。

これにはパスの指定やエラー処理が含まれます。

適切なパス指定方法を理解し、エラー処理を適切に行うことで、より堅牢で信頼性の高いプログラムを作成することができます。

○パスの指定方法

ディレクトリやファイルのパスを指定する方法は、C++のファイルシステムライブラリを使用して行います。

std::filesystem::path クラスを用いて、プラットフォームに依存しない方法でパスを操作することができます。

下記の例では、相対パスと絶対パスの指定方法を表しています。

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int main() {
    // 相対パスの指定
    fs::path relativePath = "example_dir/sub_dir";

    // 絶対パスの指定
    fs::path absolutePath = fs::current_path() / "example_dir" / "sub_dir";

    std::cout << "相対パス: " << relativePath << std::endl;
    std::cout << "絶対パス: " << absolutePath << std::endl;

    return 0;
}

このコードでは、まず相対パスを指定し、次に現在の作業ディレクトリを基に絶対パスを作成しています。

fs::current_path() 関数は現在の作業ディレクトリを取得し、それを基にパスを組み立てます。

○エラー処理のテクニック

ディレクトリ操作中に発生する可能性のあるエラーを捕捉し処理することは、堅牢なプログラムを作成する上で重要です。

C++のファイルシステムライブラリでは、例外処理を用いてエラーを捕捉することができます。

下記の例では、ディレクトリの作成時に発生する可能性のあるエラーを処理する方法を表しています。

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int main() {
    fs::path dir = "example_dir";

    try {
        // ディレクトリの作成を試みる
        if (!fs::exists(dir)) {
            fs::create_directory(dir);
        }
    } catch (const fs::filesystem_error& e) {
        // エラー発生時の処理
        std::cerr << "エラー発生: " << e.what() << std::endl;
    }

    return 0;
}

このコードでは、ディレクトリの存在を確認し、存在しない場合に作成を試みます。

エラーが発生した場合には catch ブロックが実行され、エラーメッセージが表示されます。

このようにエラー処理を行うことで、予期せぬ状況でもプログラムが適切に動作するようになります。

●注意点と対処法

C++でディレクトリ操作を行う際には、いくつかの注意点があります。

特に、異なるファイルシステムやセキュリティ、パーミッションに関する問題は、特に注意を要します。

これらの問題に適切に対処することで、プログラムの堅牢性を高め、予期せぬエラーやセキュリティ上の問題を回避することができます。

○ファイルシステムの違いへの対応

異なるオペレーティングシステムでは、ファイルシステムの仕様が異なることがあります。

例えば、WindowsとLinuxではパスの形式が異なります。

Windowsではバックスラッシュ(\)を使用し、Linuxではスラッシュ(/)を使用します。

C++のファイルシステムライブラリは、これらの違いを抽象化し、異なるシステム間での互換性を提供します。

しかし、特定のファイルシステム固有の機能を使用する場合は、そのシステムに合わせた処理が必要になることがあります。

○セキュリティとパーミッション

ディレクトリやファイルに対する操作を行う際には、セキュリティとパーミッションを考慮する必要があります。

プログラムが実行されるユーザーに必要な権限がない場合、エラーが発生する可能性があります。

特に、システムディレクトリや他のユーザーのファイルにアクセスする際には注意が必要です。

C++では、ファイルシステムライブラリを通じてパーミッションを確認し、必要に応じて権限を変更することが可能です。

ただし、セキュリティを損なうような操作は避け、必要最低限の権限で動作するようにすることが重要です。

●ディレクトリ操作のカスタマイズ方法

C++でのディレクトリ操作をカスタマイズする方法はいくつかあります。

これには、パスの動的生成やディレクトリ操作の自動化が含まれます。

これらの技術を使用することで、プログラムの柔軟性と効率性を高めることができます。

○パスの動的生成

パスの動的生成は、プログラム実行時にディレクトリやファイルのパスを生成する方法です。

これにより、プログラムはより動的で、異なる環境や要件に柔軟に対応できます。

下記のコードは、実行時にユーザー入力に基づいてディレクトリパスを生成する方法を表しています。

#include <filesystem>
#include <iostream>
#include <string>

namespace fs = std::filesystem;

int main() {
    std::string userInput;
    std::cout << "ディレクトリ名を入力してください: ";
    std::cin >> userInput;

    fs::path dir = fs::current_path() / userInput; // ユーザー入力に基づくパスの生成

    if (!fs::exists(dir)) {
        fs::create_directory(dir);
        std::cout << "ディレクトリを作成しました: " << dir << std::endl;
    } else {
        std::cout << "ディレクトリは既に存在します: " << dir << std::endl;
    }

    return 0;
}

このコードでは、ユーザーからの入力を受け取り、現在の作業ディレクトリにその入力を組み合わせて新しいパスを生成しています。

○ディレクトリ操作の自動化

ディレクトリ操作の自動化は、一連のディレクトリ操作をプログラムで自動的に実行する方法です。

これにより、手作業で行う必要のある繰り返し作業を省くことができます。

例えば、特定のパターンに基づいて複数のディレクトリを作成するスクリプトを書くことができます。

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int main() {
    for (int i = 1; i <= 5; ++i) {
        fs::path dir = fs::current_path() / ("dir" + std::to_string(i));
        if (!fs::exists(dir)) {
            fs::create_directory(dir);
            std::cout << "ディレクトリを作成しました: " << dir << std::endl;
        }
    }

    return 0;
}

このコードでは、ループを使用して5つのディレクトリを作成しています。

各ディレクトリ名は “dir1”, “dir2” などとなります。

まとめ

この記事では、C++を使用したディレクトリの作成と操作について、基本から応用、カスタマイズ方法まで幅広く解説しました。

効果的なパスの指定、エラーハンドリングのテクニック、さまざまなファイルシステムへの対応、セキュリティとパーミッションの考慮、そしてディレクトリ操作の自動化など、C++におけるディレクトリ操作の重要な側面を網羅しています。

これらの知識を活用することで、C++を用いた効率的で安全なファイルシステム操作が可能になります。

プログラミング初心者から上級者まで、この記事がC++におけるディレクトリ操作の理解と応用に役立つことを願っています。