2011-02-05 65 views
1

在我的程序中,我將用戶輸入並將其解析爲2d char數組。該陣列聲明爲:構建一個基本的shell,更具體地使用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

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

當然在現實世界中你的爭論很可能來自一個命令行字符串用戶輸入,並且它們之間可能至少有一個字符(例如空格),所以更好的方法是修改原始字符串,或者複製它,然後修改重複項,添加空終止符在每個參數之後並設置args[i]指向字符串的右偏移量。

您可以在每個步驟中做很多動態分配(malloc),但是您必須編寫代碼來處理每個可能的故障點。 :-)

+0

我想我還是有點困惑(char **)。那麼我會如何正確定義這些char數組? 此外,這是作業,所以我完全用一個簡單的例子。不要試圖把我的作業當作/。 – tgai 2011-02-05 22:25:45