0

ここから現在の作業ディレクトリを取得するためのCスニペットを見つけました。基本的に、コードは次のとおりです。

char directory[_MAX_PATH];
getcwd(directory, sizeof(directory))

それを別のファイルの別の関数に抽象化したいと思います(必要に応じて別のプラットフォームでスワップアウトできるようにします)。

現在、私は外部ファイルにあります

void getCurrentDirectory(char *directory) {
    getcwd(directory, sizeof(directory));
}

とメインファイルで

char directory[100];
getCurrentDirectory(directory);
printf("%s", *directory);

ただし、画面に印刷すると、意味がなくなります(メモリの場所を文字列として印刷しようとしている可能性がありますか?)

初心者には目がくらむほど明白なことだと思います。どうしたの?

編集:私はWindows 7を使用しています、ところで

ありがとう。

4

8 に答える 8

2

配列のサイズではなく、char*のサイズをgetcwdに渡します。

サイズパラメータを関数に渡します。

void getCurrentDirectory(char *directory, size_t size) {
    getcwd(directory, size);
}

その後:

char directory[100];
getCurrentDirectory(directory, sizeof(directory));
printf("%s", *directory);

また、Windowsを使用している場合は、MAX_PATHバッファオーバーフローの可能性を回避するために、配列サイズを事前定義済みに変更する必要があります。getcwdには時間がかかりますが、すべてのファイル関数がそうだとは思いません。

于 2011-05-23T15:57:17.827 に答える
2

この行: printf("%s", *directory);

する必要があります: printf("%s", directory);

char配列へのポインタではなく、最初の要素(directory [0])をprintfに渡します。

于 2011-05-23T15:58:08.753 に答える
2

C ++の場合は、可能であれば、boost :: filesystemを使用することをお勧めします。これにより、基盤なるプラットフォームの詳細がすべて非表示になり、バッファオーバーフローが発生しやすいC関数の代わりにC++スタイルのインターフェイスが提供されます。

于 2011-05-23T15:58:49.593 に答える
2

ここで間違っていることがいくつかあります。

void getCurrentDirectory(char *directory) 
  {
      getcwd(directory, sizeof(directory));
  }

間違い1:

`sizeof(directory)` 

ポインタのサイズ、正確にはchar*を指定します。あなたの意図は、ポインタのサイズではなく、配列のサイズを渡すことです。

間違い2:

`printf("%s", *directory);` 

配列のアドレスではなく、配列の最初の要素をprintfに渡します。あなたの意図は、最初の要素だけでなく配列全体を印刷することです。

修正された解決策

あなたがしている必要があります

void getCurrentDirectory(char *directory, size_t arrSize)  
{                                         ^^^^^^^^^^^^^^
    getcwd(directory, arrSize);
}

配列のサイズは明示的に渡されるため、関数はそれを使用できます。

配列の内容を印刷している間、主に:

   printf("%s", directory);
于 2011-05-23T15:58:56.007 に答える
1

バッファをローカルに割り当て(必要な長さがわかっていて、実際の長さがわかっている必要がある場合)、文字列を返す必要があります。

std::string
getCurrentDirectory()
{
    char results[_MAX_PATH];
    if ( getcwd( results, sizeof(results) ) == NULL )
        throw std::ios_base::failure( "Could not get current directory" );
    return std::string( results );
}

_MAX_PATHこれは単なる推測であることに注意してください。実際の最大値はコンパイル時定数ではありません(ファイルシステムに依存するため)。これを考慮した実装は、次のようになります。

std::string
getCurrentDirectory()
{
    long length = pathconf( ".", _PC_PATH_MAX );
    if ( length == -1 )
        throw std::ios_base::failure(
                "Could not determine necessary buffer length to get current directory" );
    std::string results( length, '\0' );
    if ( getcwd( &results[0], results.size() ) == NULL )
        throw std::ios_base::failure( "Could not get current directory" );
    results.resize( strlen( results.c_str() );
    return results;
}

ただし、プログラムがNFSまたはSMBにマウントされたドライブのないパーソナルシステムでのみ使用される場合、これはおそらくやり過ぎです。

于 2011-05-23T16:10:43.720 に答える
1

C ++なので、これを実行してみませんか。

std::string getCurrentDirectory()
{
    char directory[_MAX_PATH] = {};
    getcwd(directory, sizeof(directory));
    return directory;
}
于 2011-05-23T16:10:50.083 に答える
0

そのようなものを使用して、ポインタが指すメモリブロックのサイズを見つけることはできませんsizeof。ポインタ自体のサイズに評価されます。

関数を次のように変更します。

void getCurrentDirectory(char *directory, size_t buf_max)
{
    getcwd(directory, buf_max);
}
于 2011-05-23T15:57:15.257 に答える
0

今あなたが尋ねたことに答えるために:

getcwdが何らかの理由で失敗すると、directory(あなたの場合)が指す配列の内容は未定義になります。したがって、バグのある実装では、ほとんどの場合、ジャンクが表示されます。(また、からgetcwdの戻り値を確認する必要があります。失敗すると-1を返します)

さて、あなたの場合の失敗の理由は、あなたが使用して指定してsizeof(directory)いるサイズがちょうどポインタのサイズ(おそらく4)であり、あなたが印刷しようとしている現在の作業ディレクトリの名前の文字がそれ以上であるということです。これは、サイズ3以下のディレクトリで正常に機能します。

そして最後に、ここにいる他の多くの人が、おそらくそれを修正する方法をすでに説明しています。

于 2011-05-23T16:19:38.583 に答える