41

我通过以下方式看到 C 的 getcwd:man 3 cwd

我怀疑 C++ 有一个类似的,可以返回一个 std::string 。

如果是这样,它叫什么,我在哪里可以找到它的文档?

谢谢!

4

8 回答 8

34

好的,即使您已经接受了答案,我也会回答。

比包装 getcwd 调用更好的方法是使用boost::filesystem ,从函数中获取path对象。current_path()Boost 文件系统库允许你做很多其他有用的事情,否则你需要做很多字符串解析才能做,比如检查文件/目录是否存在,获取父路径,使路径完整等等。检查一下,它也是可移植的 - 很多字符串解析代码可能不会使用。

更新(2016 年):文件系统已于 2015 年作为技术规范发布,基于 Boost Filesystem v3。这意味着它可能已经在您的编译器中可用(例如 Visual Studio 2015)。对我来说,它似乎也有可能成为未来 C++ 标准的一部分(我假设是 C++17,但我不知道目前的状态)。

更新(2017 年):文件系统库已在 C++17 中与 ISO C++ 合并,用于

std::filesystem::current_path();
于 2010-02-04T22:25:12.633 回答
28

std::string的构造函数可以安全地将 achar*作为参数。令人惊讶的是还有一个Windows版本

编辑:实际上它有点复杂:

std::string get_working_path()
{
   char temp[MAXPATHLEN];
   return ( getcwd(temp, sizeof(temp)) ? std::string( temp ) : std::string("") );
}

内存没问题—— temp 是一个基于堆栈的缓冲区,std::string 构造函数进行复制。也许您可以一口气完成,但我认为标准不能保证这一点。

关于内存分配,通过 POSIX:

getcwd() 函数将当前工作目录的绝对路径名放在buf 指向的数组中,并返回buf。复制到数组的路径名不应包含符号链接的组件。size 参数是 buf 参数指向的字符数组的大小(以字节为单位)。如果 buf 是空指针,则 getcwd() 的行为未指定。

于 2010-02-04T20:59:18.507 回答
13

让我们尝试将这个简单的 C 调用重写为 C++:

std::string get_working_path()
{
    char temp [ PATH_MAX ];

    if ( getcwd(temp, PATH_MAX) != 0) 
        return std::string ( temp );

    int error = errno;

    switch ( error ) {
        // EINVAL can't happen - size argument > 0

        // PATH_MAX includes the terminating nul, 
        // so ERANGE should not be returned

        case EACCES:
            throw std::runtime_error("Access denied");

        case ENOMEM:
            // I'm not sure whether this can happen or not 
            throw std::runtime_error("Insufficient storage");

        default: {
            std::ostringstream str;
            str << "Unrecognised error" << error;
            throw std::runtime_error(str.str());
        }
    }
}

问题是,当将库函数包装在另一个函数中时,您必须假设所有功能都应该公开,因为库不知道将调用它的内容。因此,您必须处理错误情况,而不是仅仅吞下它们或希望它们不会发生。

通常最好让客户端代码只调用库函数,并在此时处理错误 - 客户端代码可能不关心错误发生的原因,因此只需要处理通过/失败情况,而不是所有错误代码。

于 2010-02-04T22:54:08.380 回答
7

您只需要编写一个小包装器。

std::string getcwd_string( void ) {
   char buff[PATH_MAX];
   getcwd( buff, PATH_MAX );
   std::string cwd( buff );
   return cwd;
}
于 2010-02-04T21:06:51.613 回答
4

getcwd()以以下方式在C中使用:

char * cwd;
cwd = (char*) malloc( FILENAME_MAX * sizeof(char) );
getcwd(cwd,FILENAME_MAX);

需要的头文件是stdio.h. 当我使用 C 编译器时,它可以完美运行。

如果我使用 C++ 编译器编译完全相同的代码,它会报告以下错误消息:

identifier "getcwd" is undefined

然后我包含unistd.h并使用 C++ 编译器进行编译。这一次,一切正常。当我切换回 C 编译器时,它仍然可以工作!

只要同时包含stdio.hunistd.h,上面的代码就适用于 C 和 C++ 编译器。

于 2013-10-30T14:18:36.920 回答
3

所有 C 函数也是 C++ 函数。如果您需要std::string,只需从char*getcwd 为您获取的内容中创建一个。

于 2010-02-04T20:59:18.693 回答
1

如上面另一个答案所述,我还使用了boost::filesystem 。我只是想补充一点,因为current_path()函数不返回 std::string,所以您需要对其进行转换。

这是我所做的:

std::string cwd = boost::filesystem::current_path().generic_string();
于 2017-06-15T16:24:59.010 回答
-2

你可以创建一个新函数,我更喜欢链接到像 boost 这样的库(除非你已经是)。

 std::string getcwd()
 {
     char* buff;//automatically cleaned when it exits scope
     return std::string(getcwd(buff,255));
 }
于 2017-07-07T18:21:58.273 回答