53

如何以与平台无关的方式在 C++ 中更改我当前的工作目录?

我找到了与direct.hWindows 兼容的头文件和与unistd.hUNIX/POSIX 兼容的 .

4

9 回答 9

50

chdir函数适用于 POSIX ( manpage ) 和 Windows (_chdir在那里调用但chdir存在别名)。

两种实现都在成功时返回零,在错误时返回 -1。正如您在手册页中看到的那样,在 POSIX 变体中可能会出现更显着的 errno 值,但对于大多数用例来说,这并不会真正产生影响。

于 2010-08-14T21:33:11.810 回答
39

现在,可以使用 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
}
于 2019-07-18T14:14:15.630 回答
19

对于 C++,boost::filesystem::current_path(setter 和 getter 原型)。

一个基于 Boost.Filesystem 的文件系统库将被添加到标准中。

于 2013-03-05T03:59:48.297 回答
16

这个跨平台示例代码,用于使用 POSIXchdir和 MS更改工作目录,如本答案_chdir中所推荐的那样。同样,为了确定当前工作目录,使用类似的和。getcwd_getcwd

这些平台差异隐藏在宏cdcwd.

根据文档,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.

MVP解决方案

$ 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;
}

OSX 列表:

$ g++ changedir.c -o changedir
$ ./changedir testing
CWD: /Users/Phil
CWD 更改为: /Users/Phil/testing

Centos 列表:

$ 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 更改为:/

Win10上市

cl.exe changedir.cpp /EHsc /nologo
changedir.cpp

c:\Users\Phil> changedir.exe test
CWD: c:\Users\Phil
CWD 改为:c:\Users\Phil\test

注意:OSX 使用clang和 Centos gnugcc后面g++的 .

于 2016-10-25T03:15:09.973 回答
9

chdir()你想做的事吗?它适用于 POSIX 和 Windows。

于 2010-08-14T21:28:25.590 回答
5

你想要chdir(2)。如果你试图让你的程序改变你的 shell 的工作目录——你不能。SO已经解决了这个问题,有很多答案。

于 2010-08-14T21:28:32.623 回答
5

你的意思是C还是C++?它们是完全不同的语言。

在 C 中,定义语言的标准不包括目录。许多支持目录的平台都有一个chdir带有char*orconst char*参数的函数,但即使它存在,声明它的标头也不是标准的。参数的含义也可能存在细微差别(例如,Windows 具有每个驱动器的目录)。

在 C++ 中,谷歌搜索会导致chdirand _chdir,并表明 Boost 没有到 chdir 的接口。但我不会进一步评论,因为我不懂 C++。

于 2010-08-14T21:44:27.273 回答
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
于 2016-10-24T21:41:40.127 回答
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\test\CWD\cwd.exe

当前工作目录为:c:\Windows 更改目录...当前工作目录为:c:\ctwoplus\progcode\test\CWD

c:\Windows>

于 2016-10-22T22:21:11.047 回答