是否有等效于 getcwd 的 C++?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2203159/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a C++ equivalent to getcwd?
提问by anon
I see C's getcwd via: man 3 cwd
我通过以下方式看到 C 的 getcwd: man 3 cwd
I suspect C++ has a similar one, that could return me a std::string .
我怀疑 C++ 有一个类似的,它可以返回一个 std::string 。
If so, what is it called, and where can I find it's documentation?
如果是这样,它叫什么,我在哪里可以找到它的文档?
Thanks!
谢谢!
采纳答案by villintehaspam
Ok, I'm answering even though you already have accepted an answer.
好的,即使您已经接受了答案,我也会回答。
An even better way than to wrap the getcwd call would be to use boost::filesystem, where you get a path
object from the current_path()
function. The Boost filesystem library allows you to do lots of other useful stuff that you would otherwise need to do a lot of string parsing to do, like checking if files/directories exist, get parent path, make paths complete etcetera. Check it out, it is portable as well - which a lot of the string parsing code one would otherwise use likely won't be.
比封装 getcwd 调用更好的方法是使用boost::filesystem,您可以在其中path
从current_path()
函数中获取对象。Boost 文件系统库允许你做很多其他有用的事情,否则你需要做很多字符串解析来做,比如检查文件/目录是否存在,获取父路径,使路径完整等。检查一下,它也是可移植的 - 否则很多字符串解析代码可能不会使用。
Update (2016):Filesystem has been published as a technical specificationin 2015, based on Boost Filesystem v3. This means that it may be available with your compiler already (for instance Visual Studio 2015). To me it also seems likely that it will become part of a future C++ standard (I would assume C++17, but I am not aware of the current status).
更新(2016 年):文件系统已于2015 年作为技术规范发布,基于 Boost Filesystem v3。这意味着它可能已经在您的编译器中可用(例如 Visual Studio 2015)。对我来说,它似乎也有可能成为未来 C++ 标准的一部分(我假设 C++17,但我不知道当前状态)。
Update (2017):The filesystem libraryhas been merged with ISO C++ in C++17, for
更新(2017年):该文件系统库被合并到ISO C ++在C ++ 17中,
std::filesystem::current_path();
回答by Kornel Kisielewicz
std::string
's constructor can safely take a char*
as a parameter. Surprisingly there's a windows versiontoo.
std::string
的构造函数可以安全地将 achar*
作为参数。令人惊讶的是,还有一个Windows 版本。
Edit: actually it's a little more complicated:
编辑:实际上它有点复杂:
std::string get_working_path()
{
char temp[MAXPATHLEN];
return ( getcwd(temp, sizeof(temp)) ? std::string( temp ) : std::string("") );
}
Memory is no problem -- temp is a stack based buffer, and the std::string constructor does a copy. Probably you could do it in one go, but I don't think the standard would guarantee that.
内存没问题—— temp 是一个基于堆栈的缓冲区,并且 std::string 构造函数会进行复制。可能你可以一次性完成,但我认为标准不能保证这一点。
About memory allocation, via POSIX:
关于内存分配,通过 POSIX:
The getcwd() function shall place an absolute pathname of the current working directory in the array pointed to by buf, and return buf. The pathname copiedto the array shall contain no components that are symbolic links. The size argument is the size in bytes of the character array pointed to by the buf argument. If buf is a null pointer, the behavior of getcwd() is unspecified.
getcwd() 函数将当前工作目录的绝对路径名放入 buf 指向的数组中,并返回 buf。复制到数组的路径名不应包含符号链接的组件。size 参数是 buf 参数指向的字符数组的大小(以字节为单位)。如果 buf 是空指针,则 getcwd() 的行为未指定。
回答by Pete Kirkham
Let's try and rewrite this simple C call as C++:
让我们尝试将这个简单的 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());
}
}
}
The thing is, when wrapping a library function in another function you have to assume that all the functionality should be exposed, because a library does not know what will be calling it. So you have to handle the error cases rather than just swallowing them or hoping they won't happen.
问题是,当将库函数包装在另一个函数中时,您必须假设所有功能都应该公开,因为库不知道将调用什么。因此,您必须处理错误情况,而不仅仅是吞下它们或希望它们不会发生。
It's usually better to let the client code just call the library function, and deal with the error at that point - the client code probably doesn't care why the error occurred, and so only has to handle the pass/fail case, rather than all the error codes.
通常最好让客户端代码只调用库函数,并在此时处理错误 - 客户端代码可能并不关心错误发生的原因,因此只需要处理通过/失败的情况,而不是所有错误代码。
回答by Brian Gianforcaro
You'll need to just write a little wrapper.
你只需要写一个小包装。
std::string getcwd_string( void ) {
char buff[PATH_MAX];
getcwd( buff, PATH_MAX );
std::string cwd( buff );
return cwd;
}
回答by Rob Kennedy
All C functions are also C++ functions. If you need a std::string
, just create one from the char*
that getcwd gets for you.
所有 C 函数也是 C++ 函数。如果您需要一个std::string
,只需从char*
getcwd 为您获取的创建一个。
回答by Zhongming Qu
I used getcwd()
in C in the following way:
我getcwd()
在 C 中以下列方式使用:
char * cwd;
cwd = (char*) malloc( FILENAME_MAX * sizeof(char) );
getcwd(cwd,FILENAME_MAX);
The header file needed is stdio.h
.
When I use C compiler, it works perfect.
需要的头文件是stdio.h
. 当我使用 C 编译器时,它工作得很好。
If I compile exactly the same code using C++ compiler, it reports the following error message:
如果我使用 C++ 编译器编译完全相同的代码,它会报告以下错误消息:
identifier "getcwd" is undefined
Then I included unistd.h
and compiled with C++ compiler.
This time, everything works.
When I switched back to the C compiler, it still works!
然后我包含unistd.h
并使用 C++ 编译器进行编译。这一次,一切正常。当我切换回 C 编译器时,它仍然有效!
As long as you include both stdio.h
and unistd.h
, the above code works for C AND C++ compilers.
只要同时包含stdio.h
and unistd.h
,上面的代码就适用于 C AND C++ 编译器。
回答by crecre
I also used boost::filesystemas stated in another answer above. I just wanted to add that since the current_path()function does not return a std::string, you need to convert it.
我还使用了boost::filesystem ,如上面另一个答案中所述。我只是想补充一点,因为current_path()函数不返回 std::string,你需要转换它。
Here is what I did:
这是我所做的:
std::string cwd = boost::filesystem::current_path().generic_string();
回答by Cody Serino
You could create a new function, which I would prefer over linking to a library like boost(unless you already are).
您可以创建一个新函数,我更喜欢链接到像 boost 这样的库(除非您已经这样做了)。
std::string getcwd()
{
char* buff;//automatically cleaned when it exits scope
return std::string(getcwd(buff,255));
}