53

プラットフォームに依存しない方法で C++ の現在の作業ディレクトリを変更するにはどうすればよいですか?

direct.hWindows 互換のヘッダー ファイルunistd.hと UNIX/POSIX 互換の を見つけました。

4

9 に答える 9

50

このchdir関数は、POSIX ( manpage ) と Windows (_chdirそこで呼び出されますが、エイリアスchdirが存在します) の両方で動作します。

どちらの実装も、成功すると 0 を返し、エラーの場合は -1 を返します。マンページでわかるように、POSIX バリアントではより明確な errno 値が可能ですが、ほとんどのユース ケースでは実際には違いはありません。

于 2010-08-14T21:33:11.810 に答える
19

C ++の場合、boost :: filesystem :: current_path(セッターとゲッターのプロトタイプ)。

Boost.Filesystemに基づくファイルシステムライブラリが標準に追加されます

于 2013-03-05T03:59:48.297 に答える
16

この回答で推奨されているように、 POSIXchdirと MSを使用して作業ディレクトリを変更するためのこのクロスプラットフォーム サンプル コード。同様に、現在の作業ディレクトリを決定するために、類似のとが使用されます。_chdirgetcwd_getcwd

これらのプラットフォームの違いは、マクロcdcwd.

ドキュメントによると、 のchdir署名は絶対または相対です。成功すると 0 を返します。に見られるように、フェッチされたパスを格納するためのバッファーが (1 つのバリアントで) 必要になるため、少し複雑になります。失敗すると NULL を返し、成功すると同じ渡されたバッファへのポインタを返します。コード サンプルでは、​​この返された char ポインターを直接使用します。int chdir(const char *path)pathchdirgetcwdchar *getcwd(char *buf, size_t size)

このサンプルは @MarcD に基づいていますが、メモリ リークを修正しています。さらに、簡潔さ、依存関係のないこと、基本的な障害/エラー チェックのみを行うこと、および複数の (共通の) プラットフォームで確実に動作するように努めました。

OSX 10.11.6、Centos7、および Win10 でテストしました。OSX と Centos の場合、以前は .NETg++ changedir.cpp -o changedirとしてビルドして実行していまし./changedir <path>た。

Win10では、でビルドしましcl.exe changedir.cpp /EHsc /nologoた。

MVP ソリューション

$ 猫 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 changed to: /Users/Phil/testing

Centos リスト:

$ g++ changedir.c -o changedir
$ ./changedir
ディレクトリが提供されていません
$ ./changedir does_not_exist
CWD: /home/phil
$ ./changedir Music
CWD: /home/phil
CWD changed to: /home/phil/Music
$ ./ changedir /
CWD: /home/phil
CWD が次のように変更されました: /

Win10 リスト

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

c:\Users\Phil> changedir.exe テスト
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

CまたはC++のことですか?それらは完全に異なる言語です。

Cでは、言語を定義する標準はディレクトリをカバーしていません。ディレクトリをサポートする多くのプラットフォームには、または引数chdirを取る関数がありますが、それが存在する場合でも、それが宣言されているヘッダーは標準ではありません。議論が何を意味するかについても微妙なことがあるかもしれません(例えば、Windowsにはドライブごとのディレクトリがあります)。char*const char*

C ++では、グーグルはとにつながりchdir_chdirBoostにchdirへのインターフェースがないことを示唆しています。しかし、私はC ++を知らないので、これ以上コメントしません。

于 2010-08-14T21:44:27.273 に答える
5

あなたがしたいchdir(2)。プログラムにシェルの作業ディレクトリを変更させようとしている場合、できません。SOには、すでにその問題に対処している回答がたくさんあります。

于 2010-08-14T21:28:32.623 に答える
3

C++ で現在のディレクトリを変更するための優れたクロスプラットフォームの方法は、ずっと前に @pepper_chico によって提案されました。このソリューションでは、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
于 2016-10-24T21:41:40.127 に答える