[2026] C++ std::filesystem::path | Cross-platform paths in C++17

[2026] C++ std::filesystem::path | Cross-platform paths in C++17

이 글의 핵심

Use std::filesystem::path to join, normalize, and inspect paths portably. Covers filename, extension, parent_path, absolute, canonical, weakly_canonical, and practical rename and backup patterns.

Introduction

std::filesystem::path is the C++17 class for portable path handling.

1. What is path?

Basic usage

아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
int main() {
    fs::path p = "/home/user/file.txt";
    fs::path p2 = "C:\\Users\\user\\file.txt";  // Windows
    
    std::cout << p << std::endl;
    std::cout << p2 << std::endl;
    
    return 0;
}

Features:

  • Platform-independent
  • Automatic separator handling (/, \\)
  • Rich API for decomposition and manipulation

2. Path manipulation

Decomposition

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
int main() {
    fs::path p = "/home/user/documents/report.pdf";
    
    std::cout << "Full: " << p << std::endl;
    std::cout << "Filename: " << p.filename() << std::endl;      // "report.pdf"
    std::cout << "Extension: " << p.extension() << std::endl;     // ".pdf"
    std::cout << "Stem: " << p.stem() << std::endl;             // "report"
    std::cout << "Parent: " << p.parent_path() << std::endl;    // "/home/user/documents"
    std::cout << "Root: " << p.root_path() << std::endl;          // "/"
    
    return 0;
}

Joining paths

다음은 cpp를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

fs::path dir = "/home/user";
fs::path file = "file.txt";
// / operator
fs::path full = dir / file;  // "/home/user/file.txt"
// /= operator
fs::path p = "/home/user";
p /= "documents";
p /= "file.txt";
std::cout << p << std::endl;  // "/home/user/documents/file.txt"
// append
fs::path p2 = "/home";
p2.append("user").append("file.txt");

3. Path normalization

Absolute paths

fs::path p = "file.txt";
fs::path abs = fs::absolute(p);
std::cout << abs << std::endl;  // e.g. "/current/directory/file.txt"

Canonical paths

아래 코드는 cpp를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

fs::path p = "/home/user/../user/./file.txt";
// Canonical (target must exist)
fs::path canonical = fs::canonical(p);
std::cout << canonical << std::endl;  // "/home/user/file.txt"
// weakly_canonical (need not exist)
fs::path p2 = "/home/user/nonexistent.txt";
fs::path weak = fs::weakly_canonical(p2);
std::cout << weak << std::endl;

Relative paths

아래 코드는 cpp를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

fs::path abs = "/home/user/documents/file.txt";
fs::path base = "/home/user";
fs::path rel = fs::relative(abs, base);
std::cout << rel << std::endl;  // "documents/file.txt"

4. Path properties

다음은 cpp를 활용한 상세한 구현 코드입니다. 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

fs::path p = "/home/user/file.txt";
if (p.is_absolute()) {
    std::cout << "Absolute path" << std::endl;
}
if (p.is_relative()) {
    std::cout << "Relative path" << std::endl;
}
if (p.empty()) {
    std::cout << "Empty path" << std::endl;
}
if (fs::exists(p)) {
    std::cout << "Exists" << std::endl;
}

5. Extensions

Changing extensions

아래 코드는 cpp를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

fs::path p = "document.txt";
p.replace_extension(".pdf");
std::cout << p << std::endl;  // "document.pdf"
p.replace_extension();
std::cout << p << std::endl;  // "document"
p.replace_extension(".docx");
std::cout << p << std::endl;  // "document.docx"

Checking extensions

아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <vector>
#include <algorithm>
fs::path p = "image.png";
if (p.extension() == ".png") {
    std::cout << "PNG file" << std::endl;
}
std::vector<std::string> image_exts = {".png", ".jpg", ".jpeg", ".gif"};
if (std::find(image_exts.begin(), image_exts.end(), p.extension()) != image_exts.end()) {
    std::cout << "Image file" << std::endl;
}

6. Comparing paths

다음은 cpp를 활용한 상세한 구현 코드입니다. 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

fs::path p1 = "/home/user/file.txt";
fs::path p2 = "/home/user/file.txt";
fs::path p3 = "/home/user/other.txt";
if (p1 == p2) {
    std::cout << "Equal" << std::endl;
}
if (p1 != p3) {
    std::cout << "Different" << std::endl;
}
// Case sensitivity is platform-dependent
// Windows: often case-insensitive
// Linux: case-sensitive

7. Practical examples

Example 1: Batch extension rename

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 에러 처리를 통해 안정성을 확보합니다, 반복문으로 데이터를 처리합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
void rename_extensions(const fs::path& dir, 
                       const std::string& old_ext, 
                       const std::string& new_ext) {
    for (const auto& entry : fs::directory_iterator(dir)) {
        if (entry.is_regular_file() && entry.path().extension() == old_ext) {
            fs::path new_path = entry.path();
            new_path.replace_extension(new_ext);
            fs::rename(entry.path(), new_path);
            std::cout << "Renamed: " << entry.path().filename() 
                      << " -> " << new_path.filename() << std::endl;
        }
    }
}
int main() {
    rename_extensions("./images", ".jpeg", ".jpg");
    return 0;
}

Example 2: Backup path

다음은 cpp를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

fs::path create_backup_path(const fs::path& original) {
    fs::path backup = original;
    backup.replace_extension();
    
    std::string backup_name = backup.filename().string() + "_backup";
    backup = backup.parent_path() / backup_name;
    backup.replace_extension(original.extension());
    
    return backup;
}
int main() {
    fs::path original = "/home/user/document.txt";
    fs::path backup = create_backup_path(original);
    
    std::cout << "Original: " << original << std::endl;
    std::cout << "Backup: " << backup << std::endl;
    
    return 0;
}

Summary

Key points

  1. path: portable path type in C++17
  2. / operator: join segments
  3. filename(), extension(), stem(): decomposition
  4. absolute(): resolve against current directory
  5. canonical(): full normalization (path must exist)

Common methods

MethodRole
filename()File name
extension()Extension including dot
stem()File name without extension
parent_path()Parent directory
root_path()Root component
replace_extension()Change extension

Next steps


... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3