std::filesystem::path::lexically_normal、std::filesystem::path::lexically_relative、std::filesystem::path::lexically_proximate
From cppreference.com
< cpp | filesystem | path
| path lexically_normal() const; |
(1) | (C++17以降) |
| path lexically_relative( const path& base ) const; |
(2) | (C++17以降) |
| path lexically_proximate( const path& base ) const; |
(3) | (C++17以降) |
1) ジェネリック形式での正規化されたパスを返します。
2) baseに対する相対パスにします。
- まず、root_name() != base.root_name() が true であるか、is_absolute() != base.is_absolute() が true であるか、または (!has_root_directory() && base.has_root_directory()) が true であるか、または relative_path() または base.relative_path() のいずれかのファイル名が ルート名として解釈できる場合、デフォルト構築されたパスを返します。
- それ以外の場合、まず *this と base の最初の不一致要素を、auto [a, b] = mismatch(begin(), end), base.begin(), base.end()) を使用して求めたかのように決定し、次に
- もし a == end() かつ b == base.end() ならば、path(".") を返します。
- そうでなければ、N を、[b, base.end()) 内の空でないファイル名要素(dot および dot-dot を除く)の数から、dot-dot ファイル名要素の数を引いたものとして定義します。N < 0 の場合、デフォルト構築されたパスを返します。
- それ以外の場合、もし N = 0 かつ a == end() || a->empty() ならば、path(".") を返します。
- それ以外の場合は、次の要素から構成されるオブジェクトを返します。
- デフォルト構築された path()、次に
- N 回の operator/=(path(".."))、次に
- 半開区間
[a,end())の各要素に対する operator/= の適用。
3) lexically_relative(base) の値が空でないパスである場合、それを返します。それ以外の場合は *this を返します。
目次 |
[編集] パラメータ
(なし)
[編集] 戻り値
1) パスの正規化された形式。
2) パスの相対形式。
3) パスの近接形式。
[編集] 例外
実装定義の例外をスローする場合があります。
[編集] 注記
これらの変換は純粋に字句的なものです。パスが存在するかどうかをチェックせず、シンボリックリンクをたどらず、ファイルシステムには一切アクセスしません。lexically_relative および lexically_proximate のシンボリックリンクをたどる対応する機能については、relative および proximate を参照してください。
Windows では、返される path はバックスラッシュ(推奨される区切り文字)を使用します。
POSIX では、相対パス内のファイル名に ルート名 として受け入れられるものはありません。
[編集] 例
このコードを実行
#include <cassert> #include <filesystem> #include <iostream> namespace fs = std::filesystem; int main() { assert(fs::path("a/./b/..").lexically_normal() == "a/"); assert(fs::path("a/.///b/../").lexically_normal() == "a/"); assert(fs::path("/a/d").lexically_relative("/a/b/c") == "../../d"); assert(fs::path("/a/b/c").lexically_relative("/a/d") == "../b/c"); assert(fs::path("a/b/c").lexically_relative("a") == "b/c"); assert(fs::path("a/b/c").lexically_relative("a/b/c/x/y") == "../.."); assert(fs::path("a/b/c").lexically_relative("a/b/c") == "."); assert(fs::path("a/b").lexically_relative("c/d") == "../../a/b"); assert(fs::path("a/b").lexically_relative("/a/b") == ""); assert(fs::path("a/b").lexically_proximate("/a/b") == "a/b"); }
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 3070 | C++17 | ルート名にもなりうるファイル名が予期せぬ結果を引き起こす可能性がある | エラーケースとして扱われる |
| LWG 3096 | C++17 | 末尾の "/" と "/." の処理が正しくない | 修正済み |
[編集] 関連項目
| (C++17) |
相対パスを構成する (関数) |