41

C の getcwd が表示されます: man 3 cwd

C++ にも同様のものがあり、 std::string を返す可能性があると思います。

もしそうなら、それは何と呼ばれていますか? また、そのドキュメントはどこにありますか?

ありがとう!

4

8 に答える 8

34

わかりました、あなたはすでに回答を受け入れていますが、私は回答しています。

getcwd 呼び出しをラップするよりもさらに良い方法は、関数からオブジェクトを取得するboost::filesystemを使用することです。Boost ファイルシステム ライブラリを使用すると、ファイル/ディレクトリが存在するかどうかの確認、親パスの取得、パスの完全化など、他の多くの文字列解析を行う必要がある他の多くの便利なことを実行できます。それをチェックしてください、それは同様に移植可能です-そうでなければ使用する多くの文字列解析コードはおそらくそうではありません.pathcurrent_path()

更新 (2016):ファイルシステムは、Boost Filesystem v3 に基づいて、2015 年に技術仕様として公開されました。これは、コンパイラで既に使用できる可能性があることを意味します (たとえば、Visual Studio 2015)。私には、それが将来の C++ 標準の一部になる可能性も高いと思われます (C++17 を想定していますが、現在の状況はわかりません)。

更新 (2017):ファイルシステム ライブラリは、C++17 で ISO C++ とマージされました。

std::filesystem::current_path();
于 2010-02-04T22:25:12.633 に答える
28

std::stringのコンストラクターは、パラメーターとして a を安全に受け取ることができchar*ます。驚いたことにWindows版もあります。

編集:実際にはもう少し複雑です:

std::string get_working_path()
{
   char temp[MAXPATHLEN];
   return ( getcwd(temp, sizeof(temp)) ? std::string( temp ) : std::string("") );
}

メモリは問題ありません。temp はスタック ベースのバッファであり、std::string コンストラクタがコピーを行います。おそらく一度に実行できますが、標準がそれを保証するとは思いません。

POSIX経由のメモリ割り当てについて:

getcwd() 関数は、現在の作業ディレクトリの絶対パス名を buf が指す配列に配置し、buf を返します。配列にコピーされるパス名には、シンボリック リンクであるコンポーネントは含まれません。size 引数は、buf 引数が指す文字配列のバイト単位のサイズです。buf が NULL ポインターの場合、getcwd() の動作は規定されていません。

于 2010-02-04T20:59:18.507 に答える
13

この単純な C 呼び出しを C++ として書き直してみましょう。

std::string get_working_path()
{
    char temp [ PATH_MAX ];

    if ( getcwd(temp, PATH_MAX) != 0) 
        return std::string ( temp );

    int error = errno;

    switch ( error ) {
        // EINVAL can't happen - size argument > 0

        // PATH_MAX includes the terminating nul, 
        // so ERANGE should not be returned

        case EACCES:
            throw std::runtime_error("Access denied");

        case ENOMEM:
            // I'm not sure whether this can happen or not 
            throw std::runtime_error("Insufficient storage");

        default: {
            std::ostringstream str;
            str << "Unrecognised error" << error;
            throw std::runtime_error(str.str());
        }
    }
}

問題は、ライブラリ関数を別の関数でラップする場合、すべての機能を公開する必要があると想定する必要があるということです。そのため、単にエラーを飲み込んだり、発生しないことを願ったりするのではなく、エラー ケースに対処する必要があります。

通常は、クライアント コードでライブラリ関数を呼び出すだけにして、その時点でエラーを処理する方が適切です。クライアント コードは、エラーが発生した理由を気にしない可能性が高いため、成功/失敗のケースのみを処理する必要があります。すべてのエラーコード。

于 2010-02-04T22:54:08.380 に答える
7

小さなラッパーを書く必要があります。

std::string getcwd_string( void ) {
   char buff[PATH_MAX];
   getcwd( buff, PATH_MAX );
   std::string cwd( buff );
   return cwd;
}
于 2010-02-04T21:06:51.613 に答える
4

getcwd()は次のようにCで使用しました:

char * cwd;
cwd = (char*) malloc( FILENAME_MAX * sizeof(char) );
getcwd(cwd,FILENAME_MAX);

必要なヘッダー ファイルはstdio.h. Cコンパイラを使用すると、完璧に動作します。

C++ コンパイラを使用してまったく同じコードをコンパイルすると、次のエラー メッセージが報告されます。

identifier "getcwd" is undefined

次にunistd.h、C++ コンパイラでインクルードしてコンパイルしました。今回は、すべてが機能します。C コンパイラに戻しても、まだ動作します。

stdio.hと の両方を含める限りunistd.h、上記のコードは C および C++ コンパイラで機能します。

于 2013-10-30T14:18:36.920 に答える
3

すべての C 関数は C++ 関数でもあります。が必要な場合は、getcwd が取得しstd::stringた から作成してください。char*

于 2010-02-04T20:59:18.693 に答える