私はおもちゃのbashシェルを書いています。今私の目標は、特定のコマンドが見つかるパスを探す環境を循環させることです。今私はパスを区切っています(例えば、 "/home/user/bin:home/user/.local/bin:/usr/local/sbin"など)を ":"で区切ります。新しい文字列finalPath
のパスに移動し、最後に "/ cmd"を連結します。strtok()は元の文字列を上書きします
私の問題は、パスの内容をfinalPath
にコピーしようとすると、私がfinalPath
に行った変更がパスに反映されることです。コードが今すぐになると、path
は "home/user/bin"に1回だけ設定され、サイクルスルーして再び同じものに設定され、トークナイザは "NULL"をヒットしてwhileループを終了します。
これは、path
とfinalPath
がメモリアドレスを共有していることを示していますが、理論的にはstrcpyが新しいコピーをメモリに作成するため、文字列とポインタで間違っている必要があります。
この予期しない動作の原因は何ですか?
編集:このコードは、私はstrcpyの
をコメントアウトするときに私のコードの機能縮小版は以下の通りです期待と同じように実行します。
int findpath(char* cmd, command_t* p_cmd) {
char* path_var;
path_var = getenv("PATH");
char* path;
char tempEnv[sizeof(path_var)];
strcpy(tempEnv, path_var);
path = strtok(tempEnv, ":");
while(path != NULL) {
char fullPath[1000];
strcpy(finalPath, path);
printf("path: %s\n", path);
printf("finalPath: %s\n", finalPath);
path = strtok(NULL, ":");
}
はい、 'strtok'は実際にソース文字列を変更します。それは記録された賞賛です。 – alain
'sizeof(path_var)'は 'path_var'の長さではありません。これはポインタサイズです。 – BLUEPIXY
ソース文字列を変更するStrtokはうまくいきます、それはstrcpyです。私は混乱しています。編集:いくつかの明確化は、私がstrcpyをコメントアウトするときにこのコードがちょうどうまくいくということです。 – teleTele