In this section, we will implement a program that just accepts a filesystem path as a command-line argument and then prints it in normalized form.
- Includes come first, and then we declare that we use namespace std and filesystem.
#include <iostream>
#include <filesystem>
using namespace std;
using namespace filesystem;
- In the main function, we check whether the user provided a command-line argument. If that is not the case, we error out and print how to use the program. If a path was provided, we instantiate a filesystem::path object from it.
int main(int argc, char *argv[])
{
if (argc != 2) {
cout << "Usage: " << argv[0] << " <path>n";
return 1;
}
const path dir {argv[1]};
- Since we can instantiate path objects from any string, we cannot be sure if the path really exists on the filesystem of the computer. In order to do that, we can use the filesystem::exists function. If it doesn't, we simply error out again.
if (!exists(dir)) {
cout << "Path " << dir << " does not exist.n";
return 1;
}
- Okay, at this point, we are pretty sure that the user provided some existing path knowing that we can ask for a normalized version of it, which we then print. filesystem::canonical returns us another path object. We could print it directly, but the path type overload of the << operator surrounds paths with quotation marks. In order to avoid that, we can print a path through its .c_str() or .string() method.
cout << canonical(dir).c_str() << 'n';
}
- Let's compile the program and play with it. When we execute it in my home directory on the relative path "src", it will print the full absolute path.
$ ./normalizer src
/Users/tfc/src
- When we run the program in my home directory again, but give it a quirky relative path description that first enters my Desktop folder, then steps out of it again using .., then enters the Documents folder and steps out again in order to finally enter the src directory, the program prints the same path as before!
$ ./normalizer Desktop/../Documents/../src
/Users/tfc/src