如何以平台无关的方式更改C ++中的当前工作目录?
我找到了与Windows兼容的direct.h
头文件和与UNIX / POSIX兼容的unistd.h
。
答案 0 :(得分:45)
chdir
函数同时适用于POSIX(manpage)和Windows(称为_chdir
,但存在别名chdir
。)
两个实现在成功时返回零,在出错时返回-1。正如您在联机帮助页中所看到的,POSIX变体中可能存在更多不同的errno值,但对于大多数用例而言,这不应该产生任何影响。
答案 1 :(得分:15)
对于C ++,boost::filesystem::current_path(setter和getter原型)。
基于Boost.Filesystem will be added to the standard的文件系统库。
答案 2 :(得分:8)
chdir()
能做你想做的吗?它适用于POSIX和Windows。
答案 3 :(得分:8)
此跨平台示例代码,用于在this answer中推荐使用POSIX chdir
和MS _chdir
更改工作目录。同样,为了确定当前工作目录,使用类似的getcwd
和_getcwd
。
这些平台差异隐藏在宏cd
和cwd
之后。
根据文档,chdir
的签名是int chdir(const char *path)
,其中path
是绝对的或相对的。成功后chdir
将返回0。 getcwd
稍微复杂一点,因为它需要(在一个变体中)缓冲区来存储所提取的路径,如char *getcwd(char *buf, size_t size)
中所示。它在失败时返回NULL,并在成功时返回指向同一传递缓冲区的指针。代码示例直接使用此返回的char指针。
该示例基于@ MarcD,但更正了内存泄漏。此外,我努力简洁,没有依赖,只有基本的失败/错误检查,并确保它在多个(通用)平台上工作。
我在OSX 10.11.6,Centos7和Win10上测试过它。对于OSX& Centos,我使用g++ changedir.cpp -o changedir
构建并运行./changedir <path>
。
在Win10上,我使用cl.exe changedir.cpp /EHsc /nologo
构建。
$ cat changedir.cpp
#ifdef _WIN32
#include <direct.h>
// MSDN recommends against using getcwd & chdir names
#define cwd _getcwd
#define cd _chdir
#else
#include "unistd.h"
#define cwd getcwd
#define cd chdir
#endif
#include <iostream>
char buf[4096]; // never know how much is needed
int main(int argc , char** argv) {
if (argc > 1) {
std::cout << "CWD: " << cwd(buf, sizeof buf) << std::endl;
// Change working directory and test for success
if (0 == cd(argv[1])) {
std::cout << "CWD changed to: " << cwd(buf, sizeof buf) << std::endl;
}
} else {
std::cout << "No directory provided" << std::endl;
}
return 0;
}
$ g ++ changedir.c -o changedir
$ ./changedir测试
CWD:/ Users / Phil
CWD更改为:/ Users / Phil / testing
$ g ++ changedir.c -o changedir
$ ./changedir
没有提供目录
$ ./changedir does_not_exist
CWD:/ home / phil
$ ./changedir音乐
CWD:/ home / phil
CWD改为:/ home / phil / Music
$ ./changedir /
CWD:/ home / phil
CWD改为:/
cl.exe changedir.cpp / EHsc / nologo
changedir.cppC:\用户\菲尔&GT; changedir.exe测试
CWD:c:\ Users \ Phil
CWD更改为:c:\ Users \ Phil \ test
注意:OSX在clang
后面使用gcc
和Centos gnu g++
。
答案 4 :(得分:5)
你想要chdir(2)
。如果您尝试让程序更改shell的工作目录 - 则不能。 SO上有很多答案已经解决了这个问题。
答案 5 :(得分:5)
您的意思是C还是C ++?它们是完全不同的语言。
在C中,定义语言的标准不包括目录。许多支持目录的平台都有一个chdir
函数,它接受char*
或const char*
参数,但即使它存在,它所声明的标题也不是标准的。关于参数的含义,也可能存在细微之处(例如,Windows具有每个驱动器目录)。
在C ++中,Google搜索会导致chdir
和_chdir
,并建议Boost没有chdir接口。但是我不会再评论,因为我不懂C ++。
答案 6 :(得分:3)
很久以前,@ pepper_chico建议使用很好的跨平台方式来改变C ++中的当前目录。此解决方案使用boost::filesystem::current_path()
。
要使用当前工作目录:
namespace fs = boost::filesystem;
fs::path cur_working_dir(fs::current_path());
要设置当前工作目录:
namespace fs = boost::filesystem;
fs::current_path(fs::system_complete( fs::path( "new_working_directory_path" ) ));
Bellow是独立的助手功能:
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"
#include <string>
namespace fs = boost::filesystem;
fs::path get_cwd_pth()
{
return fs::current_path();
}
std::string get_cwd()
{
return get_cwd_pth().c_str();
}
void set_cwd(const fs::path& new_wd)
{
fs::current_path(fs::system_complete( new_wd));
}
void set_cwd(const std::string& new_wd)
{
set_cwd( fs::path( new_wd));
}
以下是关于如何设置/获取当前工作目录的完整代码示例:
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"
#include <iostream>
namespace fs = boost::filesystem;
int main( int argc, char* argv[] )
{
fs::path full_path;
if ( argc > 1 )
{
full_path = fs::system_complete( fs::path( argv[1] ) );
}
else
{
std::cout << "Usage: tcd [path]" << std::endl;
}
if ( !fs::exists( full_path ) )
{
std::cout << "Not found: " << full_path.c_str() << std::endl;
return 1;
}
if ( !fs::is_directory( full_path ))
{
std::cout << "Provided path is not a directory: " << full_path.c_str() << std::endl;
return 1;
}
std::cout << "Old current working directory: " << boost::filesystem::current_path().c_str() << std::endl;
fs::current_path(full_path);
std::cout << "New current working directory: " << boost::filesystem::current_path().c_str() << std::endl;
return 0;
}
如果您的系统上安装了boost
,则可以使用以下命令编译此示例:
g++ -o tcd app.cpp -lboost_filesystem -lboost_system
答案 7 :(得分:2)
无法相信没有人在这个上获得赏金!!!
这是一个跨平台实现,它使用C ++获取和更改当前工作目录。所需要的只是一点宏观魔法,读取argv [0]的值,并定义一些小函数。
以下是将目录更改为当前正在运行的可执行文件的位置的代码。它可以很容易地适应于将当前工作目录更改为您想要的任何目录。
代码:
#ifdef _WIN32
#include "direct.h"
#define PATH_SEP '\\'
#define GETCWD _getcwd
#define CHDIR _chdir
#else
#include "unistd.h"
#define PATH_SEP '/'
#define GETCWD getcwd
#define CHDIR chdir
#endif
#include <cstring>
#include <string>
#include <iostream>
using std::cout;
using std::endl;
using std::string;
string GetExecutableDirectory(const char* argv0) {
string path = argv0;
int path_directory_index = path.find_last_of(PATH_SEP);
return path.substr(0 , path_directory_index + 1);
}
bool ChangeDirectory(const char* dir) {return CHDIR(dir) == 0;}
string GetCurrentWorkingDirectory() {
const int BUFSIZE = 4096;
char buf[BUFSIZE];
memset(buf , 0 , BUFSIZE);
GETCWD(buf , BUFSIZE - 1);
return buf;
}
int main(int argc , char** argv) {
cout << endl << "Current working directory was : " << GetCurrentWorkingDirectory() << endl;
cout << "Changing directory..." << endl;
string exedir = GetExecutableDirectory(argv[0]);
ChangeDirectory(exedir.c_str());
cout << "Current working directory is now : " << GetCurrentWorkingDirectory() << endl;
return 0;
}
输出:
C:\ Windows和以及c:\ ctwoplus \ progcode \测试\ CWD \ cwd.exe
当前的工作目录是:c:\ Windows 更改目录... 目前的工作目录是:c:\ ctwoplus \ progcode \ test \ CWD
C:\ Windows和GT;
答案 8 :(得分:0)
现在,在C ++ 17中可以使用std::filesystem::current_path
:
#include <filesystem>
int main() {
auto path = std::filesystem::current_path(); //getting path
std::filesystem::current_path(path); //setting path
}