Directories in C++

Here’s the translation of the Go code to C++, formatted in Markdown suitable for Hugo:

Our first program demonstrates working with directories in the file system. Here’s the full source code:

#include <iostream>
#include <filesystem>
#include <fstream>
#include <vector>

namespace fs = std::filesystem;

void check(const std::error_code& e) {
    if (e) {
        throw std::runtime_error(e.message());
    }
}

void createEmptyFile(const std::string& name) {
    std::ofstream file(name);
    file.close();
}

void visit(const fs::path& path, bool isDirectory) {
    std::cout << "  " << path.string() << " " << std::boolalpha << isDirectory << std::endl;
}

int main() {
    // Create a new sub-directory in the current working directory.
    std::error_code ec;
    fs::create_directory("subdir", ec);
    check(ec);

    // When creating temporary directories, it's good practice to remove them after use.
    // We'll use a try-catch block to ensure cleanup.
    try {
        createEmptyFile("subdir/file1");

        // We can create a hierarchy of directories, including parents.
        fs::create_directories("subdir/parent/child", ec);
        check(ec);

        createEmptyFile("subdir/parent/file2");
        createEmptyFile("subdir/parent/file3");
        createEmptyFile("subdir/parent/child/file4");

        // List directory contents
        std::cout << "Listing subdir/parent" << std::endl;
        for (const auto& entry : fs::directory_iterator("subdir/parent")) {
            std::cout << "  " << entry.path().filename().string() << " " 
                      << std::boolalpha << entry.is_directory() << std::endl;
        }

        // Change the current working directory
        fs::current_path("subdir/parent/child");

        // Now we'll see the contents of subdir/parent/child when listing the current directory.
        std::cout << "Listing subdir/parent/child" << std::endl;
        for (const auto& entry : fs::directory_iterator(".")) {
            std::cout << "  " << entry.path().filename().string() << " " 
                      << std::boolalpha << entry.is_directory() << std::endl;
        }

        // Change back to where we started.
        fs::current_path("../../..");

        // We can also visit a directory recursively, including all its sub-directories.
        std::cout << "Visiting subdir" << std::endl;
        for (const auto& entry : fs::recursive_directory_iterator("subdir")) {
            visit(entry.path(), entry.is_directory());
        }
    }
    catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }

    // Clean up
    fs::remove_all("subdir");

    return 0;
}

This program demonstrates various operations with directories:

  1. We start by creating a new directory using fs::create_directory.

  2. We use a helper function createEmptyFile to create empty files.

  3. We create a hierarchy of directories using fs::create_directories.

  4. We list directory contents using fs::directory_iterator.

  5. We change the current working directory using fs::current_path.

  6. We recursively visit all files and directories using fs::recursive_directory_iterator.

  7. Finally, we clean up by removing the entire directory tree with fs::remove_all.

To compile and run this program, you’ll need a C++17 compliant compiler. For example, using g++:

$ g++ -std=c++17 directories.cpp -o directories
$ ./directories
Listing subdir/parent
  child true
  file2 false
  file3 false
Listing subdir/parent/child
  file4 false
Visiting subdir
  subdir true
  subdir/file1 false
  subdir/parent true
  subdir/parent/child true
  subdir/parent/child/file4 false
  subdir/parent/file2 false
  subdir/parent/file3 false

This example demonstrates how to work with directories in C++ using the filesystem library, which became part of the standard library in C++17.