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

ano*_*non 33 c++ getcwd

我看到C的getcwd来自:man 3 cwd

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

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

谢谢!

vil*_*pam 26

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

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

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

更新(2017年):文件系统库被合并到ISO C++在C++ 17中,

std::filesystem::current_path();
Run Code Online (Sandbox Code Playgroud)

  • 为什么每个答案都会提升::这个提升::那个? (11认同)
  • 当然,在某些情况下,可能不值得包括boost :: filesystem库以获取当前工作目录.但是,如果他/她正在做很多文件系统的东西,那么他们也可以使用boost来完成所有这些工作. (3认同)
  • 我说的原因是因为每当有人询问如何使用API​​实现某项任务时,答案总是如此:使用此库.如果你正在开展一个大项目并且你有时间去了解你的新库是有道理的,但对于一个只想获得当前工作目录的应用程序,你想为此下载一个库?第三方库只会使调试你的应用程序变得更加困难,在这种情况下,只需添加膨胀,结果就是一个很大的胖文件. (3认同)

Kor*_*icz 23

std::string的构造函数可以安全地将a char*作为参数.令人惊讶的是,它也有一个Windows版本.

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

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

内存没问题 - temp是基于堆栈的缓冲区,std :: string构造函数执行复制.也许你可以一次性完成,但我不认为标准会保证这一点.

关于内存分配,通过POSIX:

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

  • 这个答案和Liranuna的评论都使用`getcwd`作为无参数函数,但我看到的文档显示了两个参数.我在读错了文档吗? (2认同)
  • 是char*自动释放?或者这会给我一个内存泄漏? (2认同)
  • @Bill,POSIX 规范明确指出数据是复制的,而不是分配的,因此不需要释放。 (2认同)

Pet*_*ham 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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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


Bri*_*aro 6

你需要写一个小包装器.

std::string getcwd_string( void ) {
   char buff[PATH_MAX];
   getcwd( buff, PATH_MAX );
   std::string cwd( buff );
   return cwd;
}
Run Code Online (Sandbox Code Playgroud)