入力からコマンドを受け取り、それを使用して実行するプログラムがあります(ファミリのexecl
関数である必要があります)。execvp
現在、入力行がin
であると仮定すると、単純に を使用できますか、それともより小さな文字列execl(allBeforeFirstSpaceFromIn, in);
に分割する必要がありますか? in
もしそうなら、単にすべての空白を に変更できます\0
か?
3 に答える
したがって、入力は次のような単一の文字列です。
"/bin/cat file1 file2"
"/bin/cat"
いいえ、 1 つの引数としてに渡しexecl
、"file1 file2"
別の引数として渡すことはできません。/bin/cat
という名前のファイルを開こうとする可能性がありますfile1 file2
。file1
との 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*()
。これが、この演習のポイントであると私は推測しています。
はい、引数を個別の文字列として渡す必要があります。
関数の場合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;
execを呼び出すには、基本的に 2 つの方法があります。すべての引数を 1 つずつ指定する ( execl ) か、引数の配列を指定する ( execv )。
すべての引数を で区切った長い文字列を指定すると、\0
execは最初の引数の後に他の引数が存在することを認識しません。
だからあなたはどちらかをしなければなりません
- execlを使用して、引数のリストを提供します。たとえば、(...、in、in+x、in+y、NULL)
- または、 、 、 、 ... を指す各要素の文字列の配列を作成し、execvを使用し
(char *)
ます。in
in+x
in+y
とx
( ...)はy
引数の長い文字列のインデックスです。in
command\0arg1\0arg2\0
^0 ^8 ^13
x
8 になりy
、13 になります。文字列の配列を作成できます。
char *args[] = { in, in+x, in+y, NULL };
次にexecvを使用します execv(in, args);