C++ path | "경로 처리" 가이드
이 글의 핵심
C++ path에 대한 실전 가이드입니다.
들어가며
std::filesystem::path는 C++17의 플랫폼 독립적 경로 처리 클래스입니다.
1. path란?
기본 사용
#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;
}
특징:
- 플랫폼 독립적
- 자동 구분자 변환 (/, \)
- 다양한 메서드 제공
2. 경로 조작
경로 분해
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
int main() {
fs::path p = "/home/user/documents/report.pdf";
std::cout << "전체: " << p << std::endl;
std::cout << "파일명: " << p.filename() << std::endl; // "report.pdf"
std::cout << "확장자: " << p.extension() << std::endl; // ".pdf"
std::cout << "기본명: " << p.stem() << std::endl; // "report"
std::cout << "부모: " << p.parent_path() << std::endl; // "/home/user/documents"
std::cout << "루트: " << p.root_path() << std::endl; // "/"
return 0;
}
경로 결합
fs::path dir = "/home/user";
fs::path file = "file.txt";
// / 연산자
fs::path full = dir / file; // "/home/user/file.txt"
// /= 연산자
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. 경로 변환
절대 경로
fs::path p = "file.txt";
// 절대 경로로 변환
fs::path abs = fs::absolute(p);
std::cout << abs << std::endl; // "/current/directory/file.txt"
정규 경로
fs::path p = "/home/user/../user/./file.txt";
// 정규 경로 (파일 존재 필요)
fs::path canonical = fs::canonical(p);
std::cout << canonical << std::endl; // "/home/user/file.txt"
// weakly_canonical (파일 존재 불필요)
fs::path p2 = "/home/user/nonexistent.txt";
fs::path weak = fs::weakly_canonical(p2);
std::cout << weak << std::endl;
상대 경로
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. 경로 확인
경로 타입
fs::path p = "/home/user/file.txt";
// 절대 경로?
if (p.is_absolute()) {
std::cout << "절대 경로" << std::endl;
}
// 상대 경로?
if (p.is_relative()) {
std::cout << "상대 경로" << std::endl;
}
// 비어있음?
if (p.empty()) {
std::cout << "빈 경로" << std::endl;
}
// 경로 존재?
if (fs::exists(p)) {
std::cout << "존재함" << std::endl;
}
5. 확장자 처리
확장자 변경
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"
확장자 확인
fs::path p = "image.png";
if (p.extension() == ".png") {
std::cout << "PNG 파일" << 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 << "이미지 파일" << std::endl;
}
6. 경로 비교
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 << "같음" << std::endl;
}
if (p1 != p3) {
std::cout << "다름" << std::endl;
}
// 대소문자 구분 (플랫폼 의존)
// Windows: 구분 안 함
// Linux: 구분함
7. 실전 예제
예제 1: 파일 확장자 일괄 변경
#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 << "변경: " << entry.path().filename()
<< " → " << new_path.filename() << std::endl;
}
}
}
int main() {
rename_extensions("./images", ".jpeg", ".jpg");
return 0;
}
예제 2: 백업 경로 생성
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 << std::endl;
std::cout << "백업: " << backup << std::endl;
// 백업: /home/user/document_backup.txt
return 0;
}
정리
핵심 요약
- path: C++17 플랫폼 독립 경로
- / 연산자: 경로 결합
- filename(): 파일명 추출
- extension(): 확장자 추출
- absolute(): 절대 경로 변환
- canonical(): 정규 경로 (존재 필요)
주요 메서드
| 메서드 | 설명 |
|---|---|
filename() | 파일명 |
extension() | 확장자 |
stem() | 확장자 제외 파일명 |
parent_path() | 부모 경로 |
root_path() | 루트 경로 |
replace_extension() | 확장자 변경 |
다음 단계
- C++ Filesystem
- C++ Directory Iterator
- C++ File Operations
관련 글
- C++ Directory Iterator |
- C++ File Operations |
- C++ File Status |
- C++ Filesystem 빠른 참조 |
- C++ Filesystem 개념 정리 |