2

入力からコマンドを受け取り、それを使用して実行するプログラムがあります(ファミリのexecl関数である必要があります)。execvp現在、入力行がinであると仮定すると、単純に を使用できますか、それともより小さな文字列execl(allBeforeFirstSpaceFromIn, in);に分割する必要がありますか? inもしそうなら、単にすべての空白を に変更できます\0か?

4

3 に答える 3

5

したがって、入力は次のような単一の文字列です。

"/bin/cat file1 file2"

"/bin/cat"いいえ、 1 つの引数としてに渡しexecl"file1 file2"別の引数として渡すことはできません。/bin/catという名前のファイルを開こうとする可能性がありますfile1 file2file1との 2 つのファイルを開くにfile2は、3 つの個別の引数を渡す必要があります。

execlおそらくあなたがしていることには適していません。これは可変関数です。それを呼び出すには、コードを記述するときに、渡したい引数の数を知る必要があります。したがって、この:

execl("/bin/cat", "file1", "file2");

動作するはずですが、文字列からその呼び出しを構築することはできません。

execv*()代わりに関数の 1 つを使用します。例えば:

int execv(const char *path, char *const argv[]);

引数は文字へのargvポインターであり、要素の配列の最初の要素を指す必要がありchar*ます。各要素は、終了文字列の最初の文字を指し'\0'ます。

したがって、そのポインターの配列を作成し、それぞれを初期化して文字列引数を指す必要があります。

文字列を含む配列がある場合:

"/bin/cat file1 file2"

1 つの方法は、スペースをヌル文字に置き換えることです。

"/bin/cat\0file1\0file2\0"

(最後\0はすでにそこにありました)。次にchar*、各要素が配列の先頭、または'\0'作成したばかりの文字の 1 つの直後を指すように、の配列を作成できます。このような各ポインターは、文字列への有効なポインターです。

しかし、私は必ずしもそのアプローチをお勧めしません。入力文字列の単語間に複数のスペースが含まれている場合 (おそらく単一のスペースとして扱いたい場合)、またはワイルドカードを拡張するような凝った処理を行いたい場合、問題が発生します。配列を自分で割り当てて、適切なデータをそれらにコピーすることをお勧めします。入力文字列を再利用して節約したスペースは、努力する価値がありません。

もちろん、最も簡単なアプローチは次のとおりです。

char command[] = "/bin/cat file1 file2";
system(command);
exit(0);

コマンド文字列を に渡します。これにより/bin/sh、すべての作業が行われます。しかし、それでは関数の使用方法を学習していないことになりますexec*()。これが、この演習のポイントであると私は推測しています。

于 2013-03-30T00:52:25.070 に答える
2

はい、引数を個別の文字列として渡す必要があります。

関数の場合execlX、各引数を引数として渡す必要があります。

execl(prog, arg1, arg2,...);

関数の場合execvX、C スタイルの文字列の配列を渡す必要があります。

char **argv = /* ... */;
argv[0] = "arg1";
argv[1] = "arg2";
execv(prog, args);

入力文字列を分割するには、 を使用するstrtokか、次のようにします。

char **argv = /* malloc stuff */;
char *prev = in;
cnt = 0;
while (in[0]) {
  if (in[0] == ' ') {
    in[0] = 0;
    argv[cnt++] = prev;
    prev = in + 1;
  }
  in++;
}
argv[cnt++] = prev;
argv[cnt]   = NULL;
于 2013-03-30T00:51:31.900 に答える
1

execを呼び出すには、基本的に 2 つの方法があります。すべての引数を 1 つずつ指定する ( execl ) か、引数の配列を指定する ( execv )。

すべての引数を で区切った長い文字列を指定すると、\0 execは最初の引数の後に他の引数が存在することを認識しません。

だからあなたはどちらかをしなければなりません

  • execlを使用して、引数のリストを提供します。たとえば、(...、in、in+x、in+y、NULL)
  • または、 、 、 、 ... を指す各要素の文字列の配列を作成し、execvを使用し(char *)ますinin+xin+y

x( ...)はy引数の長い文字列のインデックスです。in

command\0arg1\0arg2\0
^0       ^8    ^13

x8 になりy、13 になります。文字列の配列を作成できます。

char *args[] = { in, in+x, in+y, NULL };

次にexecvを使用します execv(in, args);

于 2013-03-30T00:53:02.900 に答える