【问题标题】:Using relative filepaths on a portable C++ application在可移植 C++ 应用程序上使用相对文件路径
【发布时间】:2010-01-21 17:20:53
【问题描述】:

我正在开发一个可移植的 C++ 应用程序。开发环境为Linux。我有一个从 Xml 文件加载数据并从中创建对象模型的代码。当前文件路径为/home/myuser/projectdir/xmlfilename.xml。当我在主目录名称不同的不同计算机上使用时,这是有问题的。我尝试了~/myuserprojectdir/xmlfilename.xml 之类的方法,但没有成功。

那么有没有一种标准的方法来定义可以在各种平台上正常工作而没有任何问题的文件名?或者任何适用于 Linux 机器的标准方法?

有什么想法吗?

【问题讨论】:

    标签: c++ cross-platform filenames


    【解决方案1】:

    您需要找到用户的主目录。为此,使用getpwent 获取用户记录并从那里获取主目录。然后将您的xml文件/myuserprojectdir/xmlfilename.xml的其余路径添加到您获得的值中。

    即使用户的主目录不是/home/$USER,这也会起作用。它适用于 linux 和 OSX,并且可能适用于安装了cygwin 的 Windows。

    这是一个工作示例为了清楚起见省略了错误检查

    #include <unistd.h>
    #include <sys/types.h>
    #include <pwd.h>
    
    main()
    {
      char* user = getlogin();
      struct passwd* userrecord;
      while((userrecord = getpwent()) != 0)
        if (0 == strcmp(user, userrecord->pw_name))
          printf("save file is %s/myuserprojectdir/xmlfilename.xml\n", userrecord->pw_dir);
    }
    

    输出:

    save file is /Users/alex/myuserprojectdir/xmlfilename.xml
    

    这就是它的工作原理(来自man getpwent):

    struct passwd * getpwent(void);
      // The getpwent() function sequentially reads the password database and is intended for programs that wish to
     process the complete list of users.
    
       struct passwd {
                   char    *pw_name;       /* user name */ // <<----- check this one
                   char    *pw_passwd;     /* encrypted password */
                   uid_t   pw_uid;         /* user uid */
                   gid_t   pw_gid;         /* user gid */
                   time_t  pw_change;      /* password change time */
                   char    *pw_class;      /* user access class */
                   char    *pw_gecos;      /* Honeywell login info */
                   char    *pw_dir;        /* home directory */ // <<----- read this one
                   char    *pw_shell;      /* default shell */
                   time_t  pw_expire;      /* account expiration */
                   int     pw_fields;      /* internal: fields filled in */
           };
    

    要获取用户名,请使用getlogin...这是来自man getlogin 的sn-p。

    char * getlogin(void);
      // The getlogin() routine returns the login name of the user associated with the current session ...
    

    【讨论】:

      【解决方案2】:

      对于可移植路径,您可能需要使用 boosts 文件系统库。

      http://www.boost.org/doc/libs/1_41_0/libs/filesystem/doc/index.htm

      【讨论】:

        【解决方案3】:

        或者任何适用于 Linux 机器的标准方法?

        在 Linux 上,查看来自 freedesktop.org 的 XDG Base Directory Specification。它指定不同类型文件的位置,例如数据、配置等

        【讨论】:

          猜你喜欢
          • 2016-08-30
          • 1970-01-01
          • 2011-12-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-04
          • 2013-12-20
          相关资源
          最近更新 更多