2013-10-15 165 views
1

我正在尝试创建一个shell,并且无法尝试用用户输入填充* argv []数组。我打电话给我的解析函数,并将每个单词存储到一个二维数组。我尝试了许多不同的方法将它直接存储到* argv []中,但最终决定尝试使用2d数组。无论如何填充* argv []指针指向存储在二维数组中的字符串?或者用指向字符串的指针填充* argv []而不使用2d数组?如何填充指针指向另一个数组中存储的字符串的字符指针数组?

我试过很多其他的东西,但我目前的尝试是调用解析函数后的while循环。

int main() { 
    int status, fRedirect, i; 
    pid_t pid; 
    char s[STORAGE]; 
    char p[MAXITEM][STORAGE]; 
    char *argv[MAXITEM]; 
    for(;;) { 
     printf("\2: "); 
     scanf("%s", s); 
     parse(s, p); 
     while(p[i] != '\0') { 
      args[i] = *p[i]; 
     } 
     if(p[0] == EOF) 
      break; 
     if(p[0] == '\0') 
      continue; 
    pid = fork(); 
    if(pid == 0) { 
     if(execvp(*p, p) == -1) { 
      printf("Execution failed!\n"); 
      exit(9); 
     } 
    } 
    if(pid != 0) { 
     wait(-1, &status, 0); 
    } 
    else { 
     fRedirect = open("/dev/null", O_WRONLY); 
     dup2(fRedirect, STDOUT_FILENO); 
    } 

} 
/*killpg(getpid(), SIGTERM);*/ 
printf("p2 terminated. \n"); 
exit(0); 
} 

void parse(char *s, char p[][STORAGE]) { 
    int i, j = 0; 
    while(*s != EOF && *s != '&' && *s != '\n' && *s != ';' && *s != '\0') { 
     for(i=0; i < strlen(s); i++) 
      p[j][i] = s[i]; 
     i = i+getword(s); 
     j++; 
    } 
} 
+0

提示:您解析函数应该从个饱argv的,可能使用的strdup每个条目,那么你的execvp应该像execvp(的argv [0],argv的);.请注意,从scanf扫描的字符串将永远不会包含EOF。 –

+0

在上面的评论中,我应该说“strtok和strdup”不只是strdup –

+0

我的解析函数应该返回char **吗?或者它是否在解析函数之外被填充? – trawww

回答

0

我看到你的代码,已包含在主函数体字符*argv[MAXITEM];()。传统上,这不是使用*argv[]的方式。主函数定义中包含代码,用于处理*argv[]的内存。通过在main()中使用字符串分析和转换函数,可以按常规方式将命令行参数解析为字符串,整数,浮点数。如果你有兴趣,这里是一个文章,解释char *argv[]有更详细一点,

对于字符串参数一个简单的例子(类似于你在做什么)采取在如何使用它下面一看,它可能会立即为您解决一些问题,例如简化您获取和解析输入的方式。

首先,回答你的问题:反正是有补*argv[]与指针存储在二维数组中的字符串?或填充*argv[]带指向字符串的指针而不使用2d数组?

但是,你可以用字符串常量填充它。的char * argv的[]是本身在主这样使用时,它可以包含一个字符串数组(指针字符串数组)的变量:

#include <ansi_c.h> 
int main(int argc, char *argv[]) //Note: the`[]` blank brackets allow any string length. 
           // the `*` allows multiple arguments 
{ 
    int i; 
    for(i=0;i<argc;i++)   //argc contains the count of cmd line arguments 
    { 
     printf("%s\n", argv[i]); //*argv[] holds multiple string arguments 
    }       

    getchar();     //optional - pauses execution so I can see output 
    return 0; 
} 

要测试:
生成作为play.exe,然后用命令行参数,如运行:

“参数1”“参数2”,“你好”

输出应该是:(本质,解析您的输入变量字符串)

enter image description here

+0

我使用了for循环的想法来打印* argv []的内容,并且似乎正在按照我现在所需的方式工作。谢谢 – trawww

0

好吧,在做了更多工作并添加了更多功能之后,以下是我目前正在使用的功能。据我所知,parse()命令现在用从命令行中取出的单词填充* argv []。

int main() { 
    pid_t pid, child_pid; 
    int argc, inputRedirect; 
    char *devNull; 
    devNull = (char *) malloc(10); 
    strcpy(devNull, "/dev/null"); 
    char *argv[MAXITEM]; 
    char commandLine[STORAGE]; 

    signal(SIGTERM, myhandler); 

    for (;;) { 
     printf("p2: "); 
     scanf("%s", commandLine); 
     if(commandLine == EOF) 
      break; 
     argc = parse(commandLine, argv); 
     if (argv[0] == '\0') 
      continue; 
     if(argv[0] = "cd") 
      changeDir(argv[1]); 
     child_pid = fork(); 
     if (child_pid < 0) { 
      printf("Cannot fork! Terminating..."); 
      exit(1); 
     } else if (child_pid == 0) { 
      CHK(inputRedirect = open(devNull, O_RDONLY)); 
      CHK(dup2(inputRedirect, STDIN_FILENO)); 
      CHK(close(inputRedirect)); 
      CHK(execvp(*argv, argv)); 
     } 
     else { 
      for(;;) { 
       CHK(pid = wait(NULL)); 
       if(pid == child_pid) 
        break; 
      } 
      printf("Child's pid is %d\n", child_pid); 
     } 
    } 
    killpg(getpid(), SIGTERM); 
    printf("p2 Terminated.\n"); 
    exit(0); 
} 

int parse(char *commandLine, char *argv[]) { 
    int argc = 0; 
    char *commandPointer = commandLine; 
    while (*commandPointer != '\0') { 
     *argv = commandPointer; 
     argc++; 
     getword(commandPointer); 
    } 
    *commandPointer = '\0'; 
    *argv = '\0'; 
    return argc; 
}