| Classes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Functions | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| File types | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Defined in header <filesystem> | ||
path canonical(conststd::filesystem::path& p); | (1) | (since C++17) |
path canonical(conststd::filesystem::path& p, std::error_code& ec); | (2) | (since C++17) |
path weakly_canonical(conststd::filesystem::path& p); | (3) | (since C++17) |
path weakly_canonical(conststd::filesystem::path& p, std::error_code& ec); | (4) | (since C++17) |
canonical() with a path argument composed of the leading elements ofp that exist (as determined bystatus(p) orstatus(p, ec)), if any, followed by the elements ofp that do not exist. The resulting path is innormal form.Contents |
| p | - | a path which may be absolute or relative; forcanonical it must be an existing path |
| ec | - | error code to store error status to |
Any overload not markednoexcept may throwstd::bad_alloc if memory allocation fails.
The functioncanonical() is modeled after the POSIXrealpath.
The functionweakly_canonical() was introduced to simplify operational semantics ofrelative().
#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(conststd::exception& ex){std::cout<<"Canonical path for "<< p2<<" threw exception:\n"<< ex.what()<<'\n';} // cleanupstd::filesystem::current_path(old);constauto count=std::filesystem::remove_all(tmp/"a");std::cout<<"Deleted "<< count<<" files or directories.\n";}
Possible output:
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.
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 2956 | C++17 | canonical has a spuriousbase parameter | removed |
(C++17) | represents a path (class)[edit] |
(C++17) | composes an absolute path (function)[edit] |
(C++17) | composes a relative path (function)[edit] |