名前空間
変種
操作

std::filesystem::canonical, std::filesystem::weakly_canonical

From cppreference.com
 
 
 
ヘッダー <filesystem> で定義
path canonical( const std::filesystem::path& p );
(1) (C++17以降)
path canonical( const std::filesystem::path& p,
                std::error_code& ec );
(2) (C++17以降)
path weakly_canonical( const std::filesystem::path& p );
(3) (C++17以降)
path weakly_canonical( const std::filesystem::path& p,
                       std::error_code& ec );
(4) (C++17以降)
1,2) パス `p` を、ドット、ドットドット要素、またはシンボリックリンクを含まない汎用形式表現の、正規化された絶対パスに変換します。`p` が絶対パスでない場合、関数は `std::filesystem::absolute(p)` によってまず絶対化されたかのように動作します。パス `p` は存在しなければなりません。
3,4) `p` の中で存在する(`status(p)` または `status(p, ec)` によって決定される)要素の先頭部分からなるパスと、`p` の中で存在しない末尾の要素からなるパスを `operator/=` で結合したパスを返します。結果のパスは正規形式です。

目次

[編集] パラメータ

p - 絶対パスまたは相対パスである可能性のあるパス。`canonical` の場合、存在しているパスである必要があります。
エラーコード - エラー状態を格納するためのエラーコード。

[編集] 戻り値

1,2) `std::filesystem::absolute(p)` と同じファイルに解決される絶対パス。
3,4) `x` は `p` の中で存在する要素の最も長い連続したシーケンスで構成されるパス、`y` は `p` の残りの存在しない末尾の要素で構成されるパスとして、`canonical(x)/y` の形式の正規化されたパス。

[編集] 例外

noexcept とマークされていないオーバーロードは、メモリ割り当てが失敗した場合に std::bad_alloc をスローする可能性があります。

1,3) 基盤となるOS APIエラーが発生した場合、最初のパス引数として `p`、エラーコード引数としてOSのエラーコードを指定して `std::filesystem::filesystem_error` がスローされます。
2,4) OS API呼び出しが失敗した場合、OS APIのエラーコードを `std::error_code&` パラメータに設定し、エラーが発生しなかった場合は `ec.clear()` を実行します。

[編集] 注記

関数 `canonical()` は、POSIX の realpath に倣っています。

関数 `weakly_canonical()` は、`relative()` の操作セマンティクスを簡略化するために導入されました。

[編集]

#include <filesystem>
#include <iostream>
 
int main()
{
    /* set up sandbox directories:
     a
     └── b
         ├── c1
         │   └── d <== current path
         └── c2
             └── e
    */
    auto old = std::filesystem::current_path();
    auto tmp = std::filesystem::temp_directory_path();
    std::filesystem::current_path(tmp);
    auto d1 = tmp / "a/b/c1/d";
    auto d2 = tmp / "a/b/c2/e";
    std::filesystem::create_directories(d1);
    std::filesystem::create_directories(d2);
    std::filesystem::current_path(d1);
 
    auto p1 = std::filesystem::path("../../c2/./e");
    auto p2 = std::filesystem::path("../no-such-file");
    std::cout << "Current path is "
              << std::filesystem::current_path() << '\n'
              << "Canonical path for " << p1 << " is "
              << std::filesystem::canonical(p1) << '\n'
              << "Weakly canonical path for " << p2 << " is "
              << std::filesystem::weakly_canonical(p2) << '\n';
    try
    {
        [[maybe_unused]] auto x_x = std::filesystem::canonical(p2);
        // NOT REACHED
    }
    catch (const std::exception& ex)
    {
        std::cout << "Canonical path for " << p2 << " threw exception:\n"
                  << ex.what() << '\n';
    }
 
    // cleanup
    std::filesystem::current_path(old);
    const auto count = std::filesystem::remove_all(tmp / "a");
    std::cout << "Deleted " << count << " files or directories.\n";
}

実行結果の例

Current path is "/tmp/a/b/c1/d"
Canonical path for "../../c2/./e" is "/tmp/a/b/c2/e"
Weakly canonical path for "../no-such-file" is "/tmp/a/b/c1/no-such-file"
Canonical path for "../no-such-file" threw exception:
filesystem error: in canonical: No such file or directory [../no-such-file] [/tmp/a/b/c1/d]
Deleted 6 files or directories.

[編集] 不具合報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
LWG 2956 C++17 canonical には、無効な `base` パラメータがあります。 削除

[編集] 関連項目

(C++17)
パスを表現する
(クラス) [編集]
(C++17)
絶対パスを構成する
(関数) [編集]
相対パスを構成する
(関数) [編集]
English 日本語 中文(简体) 中文(繁體)