2011-02-05 9 views
1

私のプログラムでは、ユーザの入力を受け取り、2dのchar配列に解析しています。配列は、次のように宣言されますより具体的にはexecvp()を使って基本的なシェルを構築する

char parsedText[10][255] = {{""},{""},{""},{""},{""}, 
      {""},{""},{""},{""},{""}}; 

と私は、ユーザーの入力をつかむためのfgetsを使用し、sscanf関数でそれを解析しています。これは私が思うようにすべて動作します。

これ以降、parsedTextをexecvpに渡したい場合は、parsedText [0]にパスが含まれている必要があります。引数が指定されている場合は、それらはparsedText [1]からparsedText [10]になければなりません。

execvp(parsedText [0]、parsedText [1])で何が問題になっていますか?

おそらく言及する価値があるのは、引数なしで "ls"のようなコマンドだけを提供すれば、うまく動作するようです。ここ

は私のコードである:

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include "308shell.h" 

int main(int argc, char *argv[]) 
{ 
char prompt[40] = "308sh"; 
char text[40] = ""; 
char parsedText[10][40] = {{""},{""},{""},{""},{""}, 
          {""},{""},{""},{""},{""}}; 

// Check for arguments to change the prompt. 
if(argc >= 3){ 
    if(!(strcmp(argv[1], "-p"))){ 
     strcpy(prompt, argv[2]); 
    } 
} 

strcat(prompt, "> "); 

while(1){ 
    // Display the prompt. 
    fputs(prompt, stdout); 
    fflush(stdout); 

    // Grab user input and parse it into parsedText. 
    mygetline(text, sizeof text); 
    parseInput(text, parsedText); 

    // Check if the user wants to exit. 
    if(!(strcmp(parsedText[0], "exit"))){ 
     break; 
    } 
    execvp(parsedText[0], parsedText[1]); 
    printf("%s\n%s\n", parsedText[0], parsedText[1]); 
} 

return 0; 
} 

char *mygetline(char *line, int size) 
{ 
if (fgets(line, size, stdin)) 
{ 
    char *newline = strchr(line, '\n'); /* check for trailing '\n' */ 
    if (newline) 
    { 
     *newline = '\0'; /* overwrite the '\n' with a terminating null */ 
    } 
} 

return line; 
} 

char *parseInput(char *text, char parsedText[][40]){ 
char *ptr = text; 
char field [ 40 ]; 
int n; 
int count = 0; 

while (*ptr != '\0') { 
    int items_read = sscanf(ptr, "%s%n", field, &n); 
    strcpy(parsedText[count++], field); 
    field[0]='\0'; 
    if (items_read == 1) 
     ptr += n; /* advance the pointer by the number of characters read  */ 
    if (*ptr != ' ') { 
     strcpy(parsedText[count], field); 
     break; /* didn't find an expected delimiter, done? */ 
    } 
    ++ptr; /* skip the delimiter */ 
} 

} 

答えて

2

execvpポインタ(char **)、ない配列へのポインタへのポインタを取ります。それはヌルポインタで終わるchar *ポインタの配列の最初の要素へのポインタであるはずです。

編集:ここexecvpに適したポインタの配列を作るために1(非常に良いではない)方法があります:あなたの引数は、おそらくコマンドライン文字列のユーザーから来る現実の世界ではもちろん

char argbuf[10][256] = {{0}}; 
char *args[10] = { argbuf[0], argbuf[1], argbuf[2], /* ... */ }; 

それらの間に少なくとも1つの文字(スペースなど)が含まれている可能性が高いので、元の文字列をその場で変更するか、複製を作成して複製を変更してヌルターミネータを追加する各引数の後に、文字列の右側のオフセットを指すようにargs[i]を設定します。

代わりに多くの動的割り当て(malloc)を実行することができますが、すべての可能な障害点を処理するコードを記述する必要があります。 :-)

+0

私はまだちょっと混乱していると思います(char **)。どのくらい正確にこれらのchar配列を正しく定義しようとしますか? これは宿題なので、私は簡単な例で完全にうまくいきます。私の宿題をやめようとしない。 – tgai

関連する問題