如何使用C++跨平台地查找用户的主目录?

34

我该如何以跨平台的方式在C++中找到用户的主目录?例如,在Linux中为/home/user,在Windows Vista中为C:\Users\user,在Windows XP中为C:\Documents And Settings\user,在苹果电脑上是什么我不确定(我认为是/User/user)。

基本上,我正在寻找一种用C++实现的方法(以下为Python示例)

os.path.expanduser("~")

4
跨平台是不可能的。标准C++没有这样的功能。 - anon
1
检查我的答案,有一种跨平台的方法:你可以使用 #ifdef 来实现 :D - sorin
请参见https://dev59.com/MHE85IYBdhLWcg3wLAQV。 - rogerdpack
3个回答

30

我认为这是不可能通过一个方法完全隐藏Windows/Unix的差异(除非,也许Boost有什么东西)。

最可移植的方式应该是在Unix上使用getenv("HOME"),在Windows上连接getenv("HOMEDRIVE")getenv("HOMEPATH")的结果。


13
这大致是Qt在QDir::homepath()中所做的:http://doc.trolltech.com/4.6/qdir.html#homePath。可能也要检查他们的源代码。 - stephan
1
QDir::homePath()的文档链接已更新。请参见http://qt-project.org/doc/qt-5/qdir.html#homePath。 - Victor Häggqvist
有没有一种方法可以在设置HOME =为其他值之前获取真实的主目录? - Bionix1441
@Bionix1441 你是什么意思? - Marcelo Cantos
1
为什么这段代码被故意混淆了呢?问题中并没有要求防止反向工程,那为什么要让它难以阅读呢? - jezza
显示剩余5条评论

24

这是可能的,而找到它的最佳方法是研究os.path.expanduser("~")的源代码,这很容易在C中复制相同的功能。

您将需要添加一些#ifdef指令来覆盖不同的系统。

以下是提供HOME目录的规则:

  • Windows:环境变量USERPROFILE或如果失败,则连接 HOMEDRIVE+HOMEPATH
  • Linux、Unix和OS X:环境变量HOME或如果失败,则使用getpwuid()(示例代码)

重要提示:许多人假设HOME环境变量在Unix上始终可用,但这并不正确,一个很好的例子就是OS X。

在OS X上,当您从GUI(而不是控制台)运行应用程序时,此变量将不存在,因此您需要使用getpwuid()。


为什么我要首先尝试使用UserProfile,如果失败了再使用HomeDrive和HomePath? - user12211554

2
家目录并不是一个跨平台的概念。你提到的个人资料文件夹根目录(%USERPROFILE%)是一个合理的比喻,但具体取决于你在获取该目录后想要做什么,你可能需要其中一个应用程序数据目录或用户的“我的文档”目录。在UNIX上,你可以在家目录中创建一个隐藏的“.myapp”目录来存储你的文件,但这在Windows上是不正确的。
你最好为每个平台编写特定的代码,以便在每种情况下都能够获得所需的目录。根据你想要多正确,使用环境变量可能足够了:在UNIX上使用HOME,在Windows上使用USERPROFILE或APPDATA(取决于你需要什么)。
至少在UNIX上(有没有Windows的开发者愿意发表评论?),如果设置了HOME环境变量,通常最好使用它,即使它与密码文件中指定的目录不一致。然后,在用户希望所有应用程序从不同的目录读取其数据的偶尔情况下,它仍将起作用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接