我看到C的getcwd来自: 男人3 cwd
我怀疑C ++有一个类似的,可以给我一个std :: string。
如果是这样,它叫什么,我在哪里可以找到它的文档?
谢谢!
答案 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.h
和unistd.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));
}