【C++17】std::filesystem で相対パスを絶対パスに変換する方法

目次

はじめに

C++でファイルパスを扱う際、「./sub/file.txt」のようなカレントディレクトリからの相対パスを、「C:\Users\Username\Documents\sub\file.txt」のような完全な絶対パスに変換したい場面があります。

C++17で導入された <filesystem> ライブラリは、この変換を行うための便利な関数を提供しています。この記事では、3つの主要なパス変換関数、absolute, canonical, weakly_canonical の使い方と、それぞれの挙動の違いについて解説します。


【前提】C++17とは?

C++17は、2017年に正式化されたC++言語の規格です。<filesystem> ライブラリはこのC++17で導入されたため、利用するにはC++17に対応したコンパイラと、適切なコンパイラ設定(および、一部の環境ではリンカ設定)が必要になります。


パス変換関数のサンプルコード

このコードは、カレントディレクトリに一時的なファイルを作成し、そのファイルへの相対パスに対して3つの異なる変換関数を適用し、結果を比較します。

完成コード

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

// filesystem名前空間のエイリアス
namespace fs = std::filesystem;

int main() {
    // テスト用のファイルを作成
    std::ofstream("tempfile.txt");
    
    fs::path relative_path = "./tempfile.txt";
    
    std::cout << "元の相対パス: " << relative_path << std::endl;
    std::cout << "----------------------------------" << std::endl;
    
    // 1. absolute(): 単純に絶対パスに変換
    std::cout << "absolute(): " << fs::absolute(relative_path) << std::endl;

    // 2. canonical(): 正規化された絶対パスに変換 (ファイルが存在する必要あり)
    std::cout << "canonical(): " << fs::canonical(relative_path) << std::endl;
    
    // 3. weakly_canonical(): 正規化された絶対パスに変換 (ファイルが存在しなくてもOK)
    fs::path non_existent_path = "./dummy/../other.txt";
    std::cout << "weakly_canonical(): " << fs::weakly_canonical(non_existent_path) << std::endl;

    // テスト用のファイルを削除
    fs::remove("tempfile.txt");
    
    return 0;
}

各関数の解説

1. std::filesystem::absolute(path)

  • 機能: 最も基本的な変換関数です。引数で渡されたパスが相対パスであれば、カレントディレクトリのパスと結合して、絶対パスを生成します。
  • 特徴:
    • パスの正規化(... の解決)は行いません
    • パスに対応するファイルやディレクトリが存在しなくても、エラーにはなりません。

2. std::filesystem::canonical(path)

  • 機能: absolute の機能に加え、パスの正規化も行います。正規化とは、.(カレントディレクトリ)や ..(親ディレクトリ)を取り除き、最も短く、一意なパス表現にすることです。
  • 特徴:
    • 返されるパスは、常に正規化された(回り道のない)絶対パスになります。
    • 【重要】 パスに対応するファイルやディレクトリが実際に存在しないと、エラー(例外)をスローします

3. std::filesystem::weakly_canonical(path)

  • 機能: canonical と同様に、パスの正規化を行いますが、エラーの扱いが異なります。
  • 特徴:
    • パスに対応するファイルやディレクトリが存在しなくても、エラーにはなりません。存在しない部分も含めて、可能な限りパスを正規化しようと試みます。
    • dummy/../other.txtother.txt に正規化されます。

まとめ

関数絶対パス化正規化ファイルの存在主な用途
absolute不要単純な絶対パスの取得
canonical必要既存ファイルへの一意なパスの取得
weakly_canonical不要これから作成するファイルパスの整形など

結論として、パスの正規化(... の解決)まで行いたい場合は canonical または weakly_canonical を、単純に絶対パスが欲しいだけであれば absolute を使う、という使い分けになります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次