在 C++ 中更改当前工作目录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3485166/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:57:10  来源:igfitidea点击:

Change the current working directory in C++

c++headerportabilityworking-directory

提问by sparkFinder

How can I change my current working directory in C++ in a platform-agnostic way?

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

I found the direct.hheader file, which is Windows compatible, and the unistd.h, which is UNIX/POSIX compatible.

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

回答by AndiDog

The chdirfunction works on both POSIX (manpage) and Windows (called _chdirthere but an alias chdirexists).

chdir函数适用于 POSIX(联机帮助页)和 Windows(_chdir在那里调用但chdir存在别名)。

Both implementations return zero on success and -1 on error. As you can see in the manpage, more distinguished errno values are possible in the POSIX variant, but that shouldn't really make a difference for most use cases.

两种实现都在成功时返回零,在错误时返回 -1。正如您在联机帮助页中看到的那样,POSIX 变体中可能有更显着的 errno 值,但这对于大多数用例来说应该没有真正的区别。

回答by pepper_chico

For C++, boost::filesystem::current_path(setter and getter prototypes).

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

A file system library based on Boost.Filesystem will be added to the standard.

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

回答by Phil

This cross-platform sample code for changing the working directory using POSIX chdirand MS _chdiras recommend in this answer. Likewise for determining the current working directory, the analogous getcwdand _getcwdare used.

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

These platform differences are hidden behind the macros cdand cwd.

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

As per the documentation, chdir's signature is int chdir(const char *path)where pathis absolute or relative. chdirwill return 0 on success. getcwdis slightly more complicated because it needs (in one variant) a buffer to store the fetched path in as seen in char *getcwd(char *buf, size_t size). It returns NULL on failure and a pointer to the same passed buffer on success. The code sample makes use of this returned char pointer directly.

根据文档,chdir的签名是int chdir(const char *path)wherepath是绝对的还是相对的。chdir成功将返回 0。getcwd稍微复杂一点,因为它需要(在一个变体中)一个缓冲区来存储获取的路径,如char *getcwd(char *buf, size_t size). 它在失败时返回 NULL,在成功时返回一个指向同一个传递缓冲区的指针。代码示例直接使用了这个返回的字符指针。

The sample is based on @MarcD's but corrects a memory leak. Additionally, I strove for concision, no dependencies, and only basic failure/error checking as well as ensuring it works on multiple (common) platforms.

该示例基于@MarcD,但纠正了内存泄漏。此外,我力求简洁,没有依赖关系,只进行基本的故障/错误检查,并确保它在多个(通用)平台上工作。

I tested it on OSX 10.11.6, Centos7, and Win10. For OSX & Centos, I used g++ changedir.cpp -o changedirto build and ran as ./changedir <path>.

我在 OSX 10.11.6、Centos7 和 Win10 上对其进行了测试。对于 OSX 和 Centos,我曾经g++ changedir.cpp -o changedir./changedir <path>.

On Win10, I built with cl.exe changedir.cpp /EHsc /nologo.

在 Win10 上,我使用cl.exe changedir.cpp /EHsc /nologo.

MVP solution

MVP解决方案

$ cat changedir.cpp

$ 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 Listing:

OSX 列表:

$ g++ changedir.c -o changedir
$ ./changedir testing
CWD: /Users/Phil
CWD changed to: /Users/Phil/testing

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

Centos Listing:

Centos列表:

$ g++ changedir.c -o changedir
$ ./changedir
No directory provided
$ ./changedir does_not_exist
CWD: /home/phil
$ ./changedir Music
CWD: /home/phil
CWD changed to: /home/phil/Music
$ ./changedir /
CWD: /home/phil
CWD changed to: /

$ g++ changedir.c -o changedir
$ ./changedir 未
提供目录
$ ./changedir does_not_exist
CWD: /home/phil
$ ./changedir Music
CWD: /home/phil
CWD 更改为: /home/phil/Music
$ ./ changedir /
CWD: /home/phil
CWD 改为: /

Win10 Listing

Win10上市

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

c:\Users\Phil> changedir.exe test
CWD: c:\Users\Phil
CWD changed to: c:\Users\Phil\test

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

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

Note: OSX uses clangand Centos gnu gccbehind g++.

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

回答by Jeremy Friesner

Does chdir()do what you want? It works under both POSIX and Windows.

是否chdir()你想要做什么?它适用于 POSIX 和 Windows。

回答by Carl Norum

You want chdir(2). If you are trying to have your program change the working directory of your shell - you can't. There are plenty of answers on SO already addressing that problem.

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

回答by Gilles 'SO- stop being evil'

Did you mean C or C++? They are completely different languages.

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

In C, the standard that defines the language doesn't cover directories. Many platforms that support directories have a chdirfunction that takes a char*or const char*argument, but even where it exists the header where it's declared is not standard. There may also be subtleties as to what the argument means (e.g. Windows has per-drive directories).

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

In C++, googling leads to chdirand _chdir, and suggests that Boost doesn't have an interface to chdir. But I won't comment any further since I don't know C++.

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

回答by Jo?o Paulo

Now, with C++17 is possible to use std::filesystem::current_path:

现在,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
}

回答by Nikita

Nice cross-platform way to change current directory in C++ was suggested long time ago by @pepper_chico. This solution uses boost::filesystem::current_path().

@pepper_chico 很久以前就提出了在 C++ 中更改当前目录的不错的跨平台方法。此解决方案使用boost::filesystem::current_path().

To get the current working directory use:

要获取当前工作目录,请使用:

namespace fs = boost::filesystem;
fs::path cur_working_dir(fs::current_path());

To set the current working directory use:

要设置当前工作目录,请使用:

namespace fs = boost::filesystem;
fs::current_path(fs::system_complete( fs::path( "new_working_directory_path" ) ));    

Bellow is the self-contained helper functions:

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

Here is my complete code-example on how to set/get current working directory:

这是我关于如何设置/获取当前工作目录的完整代码示例:

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

If boostinstalled on your system you can use the following command to compile this sample:

如果boost安装在您的系统上,您可以使用以下命令来编译此示例:

g++ -o tcd app.cpp -lboost_filesystem -lboost_system

回答by MarcD

Can't believe no one has claimed the bounty on this one yet!!!

不敢相信还没有人声称对这个人的赏金!!!

Here is a cross platform implementation that gets and changes the current working directory using C++. All it takes is a little macro magic, to read the value of argv[0], and to define a few small functions.

这是一个使用 C++ 获取和更改当前工作目录的跨平台实现。只需要一点宏魔法,读取 argv[0] 的值,并定义一些小函数。

Here is the code to change directories to the location of the executable file that is running currently. It can easily be adapted to change the current working directory to any directory you want.

这是将目录更改为当前正在运行的可执行文件所在位置的代码。它可以很容易地适应将当前工作目录更改为您想要的任何目录。

Code :

代码 :

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

Output :

输出 :

c:\Windows>c:\ctwoplus\progcode\test\CWD\cwd.exe

c:\Windows>c:\ctwoplus\progcode\test\CWD\cwd.exe

Current working directory was : c:\Windows Changing directory... Current working directory is now : c:\ctwoplus\progcode\test\CWD

当前工作目录是:c:\Windows 正在更改目录...当前工作目录现在是:c:\ctwoplus\progcode\test\CWD

c:\Windows>

c:\Windows>