最終更新日時(UTC): 2024年06月11日 13時45分38秒
Akira Takahashi が更新

履歴 編集

function
<filesystem>

# std::filesystem::canonical(C++17)

    namespace std::filesystem {
      path canonical(const path& p);                      // (1)
      path canonical(const path& p, std::error_code& ec); // (2)
    }

## 概要

パスを正規化する。

この関数は、オペレーティング・システムのファイルシステムを介して、パスの正規化を行う。ファイルシステムを使用せず、文字列処理として正規化したい場合は、`path::lexically_normal()`関数を使用する。

この関数は、正規化対象となるパスが指すファイルが存在していなければならない。存在しないファイルのパスを正規化したい場合は、`weakly_canonical()`関数を使用する。

## 効果

パス`p`に含まれる`"."` (ドットx1)、`".."` (ドットx2) を解決し、絶対パスに変換する。

パス`p`のファイル・ディレクトリが存在しない場合はエラーとなる。(2)ではエラーとなった場合、`ec`にエラー情報が書き込まれる。

## 戻り値

正規化された絶対パスが返る。

(2)ではエラーとなった場合、`path()`が返る。

## 例外

- (1) : ファイルシステムがエラーを報告する場合がある。それに加えて、指定されたファイルが存在しない場合もエラーである。エラーが発生した場合は、`std::filesystem::filesystem_error` 例外を送出する
- (2) : 仕様上は未規定だが、パスのメモリ確保で例外が発生する可能性がある

## 例

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

    namespace fs = std::filesystem;

    int main()
    {
      std::ofstream{"a.txt"};
      fs::create_directory("dir");

      // "." (ドットx1) を解決
      fs::path p1 = fs::canonical("./a.txt");
      std::cout << p1 << std::endl;

      // ".." (ドットx2) を解決
      fs::path p2 = fs::canonical("dir/../a.txt");
      std::cout << p2 << std::endl;
    }

### 出力例

    "/home/my_app/a.txt"
    "/home/my_app/a.txt"

## バージョン

### 言語

- C++17

### 処理系

- Clang: 7.0 ✅
- GCC: 8.1 ✅
- Visual C++:

## 参照

- LWG Issue 2956. `filesystem::canonical()` still defined in terms of `absolute(p, base)`