我通过以下方式看到 C 的 getcwd:man 3 cwd
我怀疑 C++ 有一个类似的,可以返回一个 std::string 。
如果是这样,它叫什么,我在哪里可以找到它的文档?
谢谢!
好的,即使您已经接受了答案,我也会回答。
比包装 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();
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() 的行为未指定。
让我们尝试将这个简单的 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());
}
}
}
问题是,当将库函数包装在另一个函数中时,您必须假设所有功能都应该公开,因为库不知道将调用它的内容。因此,您必须处理错误情况,而不是仅仅吞下它们或希望它们不会发生。
通常最好让客户端代码只调用库函数,并在此时处理错误 - 客户端代码可能不关心错误发生的原因,因此只需要处理通过/失败情况,而不是所有错误代码。
您只需要编写一个小包装器。
std::string getcwd_string( void ) {
char buff[PATH_MAX];
getcwd( buff, PATH_MAX );
std::string cwd( buff );
return cwd;
}
我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.h
和unistd.h
,上面的代码就适用于 C 和 C++ 编译器。
所有 C 函数也是 C++ 函数。如果您需要std::string
,只需从char*
getcwd 为您获取的内容中创建一个。
如上面另一个答案所述,我还使用了boost::filesystem 。我只是想补充一点,因为current_path()函数不返回 std::string,所以您需要对其进行转换。
这是我所做的:
std::string cwd = boost::filesystem::current_path().generic_string();
你可以创建一个新函数,我更喜欢链接到像 boost 这样的库(除非你已经是)。
std::string getcwd()
{
char* buff;//automatically cleaned when it exits scope
return std::string(getcwd(buff,255));
}