用C ++更改当前工作目录

时间:2010-08-14 21:21:00

标签: c++ header portability working-directory

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

我找到了与Windows兼容的direct.h头文件和与UNIX / POSIX兼容的unistd.h

9 个答案:

答案 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

这些平台差异隐藏在宏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&amp; 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测试
  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:\用户\菲尔&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
}