1

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

我尝试了很多其他的事情,但我目前的尝试是调用解析函数后的 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++;
    }
}
4

2 回答 2

0

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

对于字符串参数的简单示例(类似于您正在执行的操作),请看下面如何使用它,它可能会立即为您解决几个问题,例如简化您获取和解析输入的方式。

首先,您的问题的答案:无论如何要填充 *argv[] 指向存储在二维数组中的字符串的指针? 或者在不使用二维数组的情况下填充 *argv[] 指向字符串的指针?

不。

但是,您可以用字符串常量填充它。char *Argv[] 本身是一个变量,在 main 中使用时可以包含字符串数组(指向字符串数组的指针),如下所示:

#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,然后使用命令行参数运行它,例如:

“argument1” “argument2” “你好”

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

在此处输入图像描述

于 2013-10-15T02:51:18.147 回答
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;
}
于 2013-10-15T21:56:40.323 回答