如何以跨平台的方式更改C++中的当前工作目录?
我找到了direct.h
头文件,适用于Windows,还有unistd.h
,适用于UNIX/POSIX。
如何以跨平台的方式更改C++中的当前工作目录?
我找到了direct.h
头文件,适用于Windows,还有unistd.h
,适用于UNIX/POSIX。
现在,使用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
}
chdir()
)时,通常需要在不同的平台上包含不同的头文件。如果针对Windows进行编译,GCC会定义_WIN32
,因此您可以使用#include
与之配合选择一个头文件。 - RBerteig#ifdef _MSC_VER
检查 Visual Studio,并包含 direct.h
头文件。如果未定义,则使用 unistd.h
。 这应该足够了,因为在 Windows 上的另一个主要编程环境 MinGW已有 unistd.h
头文件。 - AndiDogchdir
已经被弃用。 - noɥʇʎԀʎzɐɹƆ_chdir != chdir
_chdir
不是跨平台的,而 chdir
已经被弃用。 - Jonathan Mee对于C++,boost::filesystem::current_path(setter和getter原型)。
基于Boost.Filesystem的文件系统库将被添加到标准库中。
这是一个跨平台的示例代码,用于使用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,成功时返回指向相同传递的缓冲区的指针。代码示例直接利用了该返回的字符指针。
该示例基于@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 testing
当前工作目录: /Users/Phil
工作目录更改为:/Users/Phil/testing
$ g++ changedir.c -o changedir
$ ./changedir
未提供目录
$ ./changedir does_not_exist
当前工作目录: /home/phil
$ ./changedir Music
当前工作目录: /home/phil
工作目录更改为: /home/phil/Music
$ ./changedir /
当前工作目录: /home/phil
工作目录更改为: /
cl.exe changedir.cpp /EHsc /nologo
changedir.cppc:\Users\Phil> changedir.exe test
当前工作目录: c:\Users\Phil
工作目录更改为: c:\Users\Phil\test
注意:OSX使用clang
,Centos使用gcc
(在g++
背后)。
chdir()
函数是否符合您的需求?它可以在POSIX和Windows下使用。
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" ) ));
#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
std::string
和 boost::filesystem::path
。 - Nikitaboost
命名和典型的 C++ 代码风格。 - Nikita难以相信没有人领取这个奖金!
以下是一个使用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\test\CWD\cwd.exe
当前工作目录为:c:\Windows 正在更改目录... 当前工作目录已更改为:c:\ctwoplus\progcode\test\CWD
c:\Windows>
filesystem
在 C++17 中确立了一种更改工作目录的标准方式。pepper_chico 的回答 已经指出了这一点。filesystem
目前在 g++5.3 和 Visual Studio 2015 中作为可选包含文件提供。如果您正在使用这个环境,我可以使用#ifdef
为您编写一个跨平台访问filesystem
的答案。 - Jonathan Mee