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
#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
#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
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
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
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
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
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
#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
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
#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
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
- path: portable path type in C++17
/operator: join segments- filename(), extension(), stem(): decomposition
- absolute(): resolve against current directory
- canonical(): full normalization (path must exist)
Common methods
| Method | Role |
|---|---|
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
Related posts
- C++ Directory Iterator
- C++ File Operations
- C++ File Status
- C++ Filesystem quick reference
- C++ Filesystem overview
Frequently Asked Questions (FAQ)
Q. When would I use this in practice?
A. Use std::filesystem::path to join, normalize, and inspect paths portably. Covers filename, extension, parent_path, absol…
Q. What should I read before this?
A. Follow the previous article or related articles links at the bottom of each post to learn in sequence. See the C++ series index for the full picture.
Q. Where can I study this more deeply?
A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.
Related Articles (Internal Links)
Other articles related to this topic.
- [2026] C++ std::filesystem 심화 | POSIX·Win32 구현
- C++ Directory Iterator | ‘디렉토리 순회’ 가이드
- C++ Filesystem 빠른 참조 | ‘파일시스템’ C++17 라이브러리 가이드
Keywords Covered in This Article (Related Search Terms)
This article covers C++, path, filesystem, C++17, cross-platform.