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

发布于 2024-09-14 12:40:01 字数 126 浏览 14 评论 0原文

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

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

猫烠⑼条掵仅有一顆心 2024-09-21 12:40:01

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

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

#include <filesystem>
int main() {
    auto path = std::filesystem::current_path(); //getting path
    std::filesystem::current_path(path); //setting path
}
与他有关 2024-09-21 12:40:01

chdir 函数适用于 POSIX (联机帮助页) 和 Windows (称为 _chdir ,但有一个别名 <代码>chdir存在)。

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

The chdir function works on both POSIX (manpage) and Windows (called _chdir there but an alias chdir exists).

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.

调妓 2024-09-21 12:40:01

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

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

蓝梦月影 2024-09-21 12:40:01

此跨平台示例代码用于按照 这个答案。同样,为了确定当前工作目录,类似的 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 -ochangedir 来构建并作为 ./changedir 运行。

在 Win10 上,我使用 cl.exe Changedir.cpp /EHsc /nologo 进行构建。

MVP解决方案

$catchangedir.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++ 已更改目录.c -o 已更改目录
$ ./changedir 测试
CWD:/用户/菲尔
CWD 更改为:/Users/Phil/testing

Centos 列表:

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

Win10 列表

cl.exe 更改了dir.cpp /EHsc /nologo
更改目录.cpp

c:\Users\Phil> Changedir.exe 测试
CWD: c:\Users\Phil
CWD 更改为:c:\Users\Phil\test

注意:OSX 在 g++ 后面使用 clang 和 Centos gnu gcc

This cross-platform sample code for changing the working directory using POSIX chdir and MS _chdir as recommend in this answer. Likewise for determining the current working directory, the analogous getcwd and _getcwd are used.

These platform differences are hidden behind the macros cd and cwd.

As per the documentation, chdir's signature is int chdir(const char *path) where path is absolute or relative. chdir will return 0 on success. getcwd is 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.

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.

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

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

MVP solution

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

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

Centos Listing:

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

Win10 Listing

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

Note: OSX uses clang and Centos gnu gcc behind g++.

我很坚强 2024-09-21 12:40:01

chdir() 是否满足您的要求?它可以在 POSIX 和 Windows 下运行。

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

书信已泛黄 2024-09-21 12:40:01

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

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.

尤怨 2024-09-21 12:40:01

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

在 C 中,定义该语言的标准不包括目录。许多支持目录的平台都有一个 chdir 函数,该函数采用 char*const char* 参数,但即使它存在,标头也位于其所在位置声明不标准。该参数的含义也可能有一些微妙之处(例如,Windows 有每个驱动器的目录)。

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

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

In C, the standard that defines the language doesn't cover directories. Many platforms that support directories have a chdir function 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).

In C++, googling leads to chdir and _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++.

无人问我粥可暖 2024-09-21 12:40:01

@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" ) ));    

波纹管是独立的辅助函数:

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

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

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

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().

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:

#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 boost installed on your system you can use the following command to compile this sample:

g++ -o tcd app.cpp -lboost_filesystem -lboost_system
策马西风 2024-09-21 12:40:01

不敢相信还没有人领取这个赏金!!!

这是一个跨平台实现,它使用 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>

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.

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

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

c:\Windows>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文