Hey guys I am starting to learn C++, and there is one thing I do not understand - what is my actual path?
So, for example, in Python, the actual path of xyz.py
is where I run python3 xyz.py
. But, how does it work in C++?
My C++ project looks like this:
--build
--data
--exampleData
--src
--example1
--include
--src
-FileToRun.cc
I build my project "example1" to the build
directory. In my project, I want to open the exampleData
, what is the relative path for it? Is it relative to the position of FileToRun.cc
? Or is it dependentt on how I execute it, like in Python? Or something else?
A relative path is relative to the calling process's current working directory, wherever that happens to be pointing at the moment it is used. The working directory can be specified by a parent process. Or change dynamically during the current process's lifetime. So you can't really rely on the working directory being where you expect at any given moment.
Your C++ app's default working directory may be your build
folder, depending on your configuration, but it will certainly not be your src
folder, unless you explicitly set it up that way (for instance, by opening a terminal to the src
folder and then running the executable without changing folders. Or creating a shortcut to the executable and setting the working directory in the shortcut's properties).
This works the same in Python and C++, and any other language, as it is a feature of the OS, not the app.
If you want to ensure that your relative paths are relative to your executable (or any other root), then you should convert them to absolute paths at runtime. Retrieve your executable's absolute folder path (such as with GetModuleFileName()
on Windows, or argv[0]
in main()
, etc, then strip off the executable's filename), or whatever absolute root you want. Then append your relative path. And then resolve any remaining .
/..
as needed.
So, for example, if you have <path>/build/example1.exe
and want to access <path>/data/exampleData
, then you would
<path>/build/example1.exe
<path>/build/
../data/exampleData
to get <path>/build/../data/exampleData
/build/../data/
to /data/
<path>/data/exampleData
There are APIs to help with this task. Such as PathRemoveFileSpec()
and PathCombine()
/PathAppend()
/PathCanonicalize()
on Windows. Or the <filesystem>
library in C++17.