C++ 中的实际路径是什么?如何获取相对路径?

What is the actual path in C++ and how do I get the relative path?

大家好,我开始学习 C++,有一件事我不明白——我的实际路径是什么?

因此,例如,在Python中,xyz.py的实际路径是我运行python3 xyz.py所在的位置。但是,它在 C++ 中如何工作?

我的 C++ 项目如下所示:

--build
--data
  --exampleData
--src
  --example1
    --include
    --src
      -FileToRun.cc

我将项目“example1”构建到 build 目录。在我的项目中,我想打开exampleData,它的相对路径是什么?是相对于FileToRun.cc的位置?或者它取决于我如何执行它,就像在 Python 中一样?或者别的什么?

相对路径是相对于调用进程的当前工作目录的,无论它在使用时恰好指向何处。工作目录可以由父进程指定。或者在当前进程的生命周期内动态改变。因此,您不能真正依赖工作目录在任何给定时刻的预期位置。

您的 C++ 应用程序的默认工作目录 可能 是您的 build 文件夹,具体取决于您的配置,但肯定不会是您的 src 文件夹,除非您以这种方式明确设置它(例如,通过打开终端到 src 文件夹,然后 运行 可执行文件而不更改文件夹。或者创建可执行文件的快捷方式并将工作目录设置为快捷方式的属性)。

这在 Python 和 C++ 以及任何其他语言中都是一样的,因为它是 OS 而不是应用程序的功能。

如果你想确保你的相对路径是相对于你的可执行文件(或任何其他根),那么你应该在运行时将它们转换为绝对路径。检索可执行文件的绝对文件夹路径(例如 Windows 上的 GetModuleFileName()main() 中的 argv[0] 等,然后剥离可执行文件的文件名),或任何绝对根目录想。然后附加您的相对路径。然后根据需要解决任何剩余的 ./..

因此,例如,如果您有 <path>/build/example1.exe 并且想要访问 <path>/data/exampleData,那么您将

  • <path>/build/example1.exe
  • 开始
  • 去掉文件名得到<path>/build/
  • 附加../data/exampleData得到<path>/build/../data/exampleData
  • /build/../data/解析为/data/
  • 因此给你留下 <path>/data/exampleData

有 API 可以帮助完成此任务。例如 PathRemoveFileSpec() 和 Windows 上的 PathCombine()/PathAppend()/PathCanonicalize()。或者 C++17 中的 <filesystem> library.

我想你问的是 current working directory(a.k.a.CWD) while 运行ning 你的可执行文件以及从那里如何访问位于某个特定位置的数据目录。

这取决于您如何 运行 可执行文件。

  1. 如果您从终端 运行 它,您 运行 可执行文件所在的当前目录很可能是 CWD。在这种情况下,您应该已经知道如何获取相对路径了。
  2. 如果您通过 IDE 运行(例如 Windows 上的 Visual Studio),build 目录可能是 CWD,因为VS倾向于将输出目录设置为CWD。在这种情况下,我建议您检查项目设置,因为我刚才所说的在 IDE 中完全可以自定义。如果在设置中将 build 设置为 CWD,您可以通过 ../data/exampleData/<your file>
  3. 访问您的数据

尽管在#2 的情况下您可以在 IDE 中设置 CWD,但您可能会发现在释放可执行文件后定位包含数据的目录很棘手。 (即,您将其构建为发布版本以发布它)因为相对路径可能会根据您 运行 可执行文件的位置而改变,这是由于 #1 中所描述的。因此,我建议您解决此问题的方法是通过在您的程序中显式调用系统函数来将可执行文件所在的目录设置为 CWD,以便您的可执行文件始终能够找到您的资产,无论如何你运行吧。

  • 在 Windows 上,您可以使用 SetCurrentDirectory (link)。
  • 在 Linux-ish 系统上,您可以使用 chdir (link)