是否有一个与getcwd等效的C ++?

时间:2010-02-04 20:56:44

标签: c++ getcwd

我看到C的getcwd来自: 男人3 cwd

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

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

谢谢!

8 个答案:

答案 0 :(得分:24)

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

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

更新(2016):文件系统已于2015年以technical specification发布,基于Boost Filesystem v3。这意味着它可能已经与您的编译器一起提供(例如Visual Studio 2015)。对我来说,它似乎也有可能成为未来C ++标准的一部分(我会假设C ++ 17,但我不知道当前的状态)。

更新(2017): filesystem library已与C ++ 17中的ISO C ++合并,用于

std::filesystem::current_path();

答案 1 :(得分:21)

std::string的构造函数可以安全地将char*作为参数。令人惊讶的是,还有一个windows version

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

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()的行为。

答案 2 :(得分:12)

让我们尝试将这个简单的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());
        }
    }
}

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

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

答案 3 :(得分:5)

你需要写一个小包装器。

std::string getcwd_string( void ) {
   char buff[PATH_MAX];
   getcwd( buff, PATH_MAX );
   std::string cwd( buff );
   return cwd;
}

答案 4 :(得分:3)

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

答案 5 :(得分:3)

我通过以下方式在C中使用getcwd()

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 ++编译器。

答案 6 :(得分:1)

我还使用了 boost :: filesystem ,如上面的另一个答案中所述。我只是想补充一点,因为 current_path()函数没有返回std :: string,你需要转换它。

这是我做的:

std::string cwd = boost::filesystem::current_path().generic_string();

答案 7 :(得分:-1)

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

 std::string getcwd()
 {
     char* buff;//automatically cleaned when it exits scope
     return std::string(getcwd(buff,255));
 }