【问题标题】:Opening a file in c++, relative or absolute?用c ++打开文件,相对还是绝对?
【发布时间】:2012-04-23 13:28:48
【问题描述】:

我正在尝试在大代码中打开文件。

有人告诉我,在处理文件时,使用绝对路径而不是相对路径可能是更好的做法。但是,此代码将由不同的人使用,他们可能将源放在不同的位置(例如 /home/username 或 /home/username/desktop/),因此我认为使用相对路径可能会更好访问我的配置文件,因为我知道它与我的 cpp 文件的关系。

以下是与我的问题相关的文件位置的简短总结:

  • 我要读取的文件是/home/me/myproject/config/myfile.txt

  • 我从中读取的文件是 /home/me/myproject/src/myfile.cpp

  • 包含'main'的文件也是/home/me/myproject/src/myfile.cpp(这个文件很大)。

我正在从 Eclipse 启动可执行文件。我认为eclipse将工作目录设置为'main'所在的目录(/home/me/myproject/src/)。

当我要调用file.open() 时,工作目录(getcwd()) 现在是/home/me/myproject/,这让我感到困惑。显然,工作目录被 main() 和我调用 file.open() 之间的代码修改了。

我的问题是:依赖工作目录似乎很容易出错,如果它可以被程序的另一部分更改。另一方面,鉴于我不知道其他开发人员通常将其源代码放在哪里,我应该怎么知道我的配置路径在哪里?

【问题讨论】:

  • 告诉你的应用程序配置文件在命令行的什么位置。
  • 您需要它在任何平台上工作,还是只在类似 UNIX 的平台上工作?

标签: c++ eclipse file directory


【解决方案1】:

我正在从 Eclipse 启动可执行文件。我认为日食设置 工作目录到'main'所在的目录 (/home/me/myproject/src/)。

你确定吗?在我看来,它是项目文件夹的顶层(即,类似于“/home/eclipse/myproject”,而不是“/home/eclipse/src”。这可以解释原因:

工作目录 (getcwd()) 现在是 /home/me/myproject/。

还有别的吗?除非您明确做了一些事情来导致它“被程序的另一部分更改”,否则它不太可能被“更改”。

我不清楚您是否了解源代码可执行文件之间的区别。您的源代码文件不是“运行”。它被编译成可执行文件,这就是运行的内容。使用 eclipse,这些默认放入 Release/ 或 Debug/ (看看),而不是 src/ 目录。 eclipse 使用顶级目录的(可能的)原因是这些版本之间的一致性,因此您可以,例如,相对于它的输出。

我的问题是:依赖工作似乎很容易出错 目录,

无论如何,这绝对是真的。有一些特定于操作系统的方法可以获取用户主目录的路径。您应该得到它,并在文档中指定要保存配置的位置。如果用户不能正确地做到这一点,这不是你的错——而是发出一条信息性消息,例如。 “找不到配置文件!”。

我应该怎么知道我的配置路径在哪里 是,鉴于我不知道其他开发人员通常放在哪里 他们的来源?

请注意,“其他开发人员”根本不需要包含源代码,因为它不是运行可执行文件所必需的。

【讨论】:

    【解决方案2】:

    接受文件位置作为参数总是一个好主意,这样使用您的软件的人可以轻松尝试不同的配置。

    您始终可以做的是找出当前正在运行的二进制文件的位置。如果找不到直接的方法,请使用getcwd()argv[0] 的组合。工作目录在命令运行后改变,如果进程本身没有改变的话。

    然后你可以截掉文件名并将配置文件的名称附加到路径中(在以下示例中存储在字符串base中)。 这是一些代码,可以确定路径是绝对路径还是相对路径,并相应地附加它。您需要 boost_filesystem 才能跨平台:

    #ifdef WITH_BOOST_FILESYSTEM
        boost::filesystem::path basepath(base), filepath(filename);
        if (!basepath.is_complete()) {
            basepath = filepath.remove_leaf() /= basepath;
            base = basepath.string();
        }
    #elif __unix__
        if (base[0] != '/') {
            char *f = strdup(filename.c_str()), *d = dirname(f);
            base = string(d).append("/").append(base);
            free(f);
        }
    #else
        std::cerr << "Warning: only absolute file paths accepted." << std::endl;
    #endif
        base.append("/");
    

    【讨论】:

    • 否决在 std::string 上使用 strdup,不释放 strdup 返回的内存和缺少 base 声明。
    • 这是一段代码摘录,你可以从文字中猜到。但无论如何,感谢您善意的调试工作。
    • 来自 dirname 手册页:“dirname() 和 basename() 都可能修改路径的内容,因此在调用其中一个函数时可能需要传递一个副本。”这就是为什么 strdup 是必要的。 c_str() 只给出一个 const 指针。
    • “但是谢谢你的好意”。我不在乎借口。改为编写干净/优雅的代码。如果base 为空,__unix__ 版本可能会崩溃。
    • 我觉得你应该改变态度。
    猜你喜欢
    • 2010-12-29
    • 2011-11-21
    • 2011-04-29
    • 2015-11-13
    • 1970-01-01
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    相关资源
    最近更新 更多