C 如何用指向存储在另一个数组中的字符串的指针填充字符指针数组?

C 如何用指向存储在另一个数组中的字符串的指针填充字符指针数组?,c,arrays,shell,pointers,C,Arrays,Shell,Pointers,我正在尝试创建一个shell,但在尝试用用户输入填充*argv[]数组时遇到问题。我调用parse函数,并将每个单词存储到一个2d数组中。我尝试了许多不同的方法将其直接存储到*argv[],但最终决定尝试使用2d数组。是否仍要使用指向2d数组中存储的字符串的指针来填充*argv[]?或者用指向字符串的指针填充*argv[],而不使用2d数组 我尝试了很多其他方法,但我目前的尝试是调用parse函数后的while循环 int main() { int status, fRedirect, i

我正在尝试创建一个shell,但在尝试用用户输入填充*argv[]数组时遇到问题。我调用parse函数,并将每个单词存储到一个2d数组中。我尝试了许多不同的方法将其直接存储到*argv[],但最终决定尝试使用2d数组。是否仍要使用指向2d数组中存储的字符串的指针来填充*argv[]?或者用指向字符串的指针填充*argv[],而不使用2d数组

我尝试了很多其他方法,但我目前的尝试是调用parse函数后的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++;
    }
}
intmain(){
国际地位,FredDirect,i;
pid_t pid;
字符s[存储];
字符p[MAXITEM][STORAGE];
字符*argv[MAXITEM];
对于(;;){
printf(“\2:”);
scanf(“%s”,s);
解析(s,p);
而(p[i]!='\0'){
args[i]=*p[i];
}
if(p[0]==EOF)
打破
如果(p[0]='\0')
持续
pid=fork();
如果(pid==0){
如果(execvp(*p,p)=-1){
printf(“执行失败!\n”);
出口(9);
}
}
如果(pid!=0){
等待(-1,&状态,0);
}
否则{
fRedirect=open(“/dev/null”,仅限O_wr);
dup2(FredDirect,标准文件号);
}
}
/*killpg(getpid(),SIGTERM)*/
printf(“p2终止。\n”);
出口(0);
}
void解析(char*s,char p[][存储]){
int i,j=0;
而(*s!=EOF&&*s!='&'&'&&&*s!='\n'&&&&*s!=';'&&&*s!='\0'){
对于(i=0;i
我在您的代码中看到您包含了char
*argv[MAXITEM]。这在传统上不是使用
*argv[]
的方式。主函数定义中包含处理
*argv[]
内存的代码。可以使用main()中的字符串解析和转换函数,以通常的方式将命令行参数解析为字符串、整数和浮点数。如果你感兴趣,这里有一篇文章解释了,并提供了更多的细节

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

首先,您的问题的答案是:是否仍然可以使用指向存储在2d数组中的字符串的指针来填充
*argv[]
?或者用指向字符串的指针填充
*argv[]
,而不使用2d数组

没有

但是,您可以用字符串常量填充它。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;
}
#包括
int main(int argc,char*argv[])//注意:`[]`空括号允许任何字符串长度。
//`*`允许多个参数
{
int i;

对于(i=0;iOk),在对其进行了更多的研究并添加了更多的功能之后,以下是我目前正在使用的功能。据我所知,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;
}
intmain(){
pid_t pid,子pid;
int argc,inputRedirect;
char*devNull;
devNull=(char*)malloc(10);
strcpy(devNull,“/dev/null”);
字符*argv[MAXITEM];
字符命令行[存储];
信号(SIGTERM,myhandler);
对于(;;){
printf(“p2:”);
scanf(“%s”,命令行);
如果(命令行==EOF)
打破
argc=parse(命令行,argv);
如果(argv[0]=='\0')
持续
如果(argv[0]=“cd”)
changeDir(argv[1]);
child_pid=fork();
if(子项pid<0){
printf(“无法分叉!终止…”);
出口(1);
}else if(子项pid==0){
CHK(inputRedirect=open(devNull,仅限ordu));
CHK(dup2(inputRedirect,STDIN_FILENO));
CHK(close(inputRedirect));
CHK(execvp(*argv,argv));
}
否则{
对于(;;){
CHK(pid=wait(NULL));
如果(pid==子项\U pid)
打破
}
printf(“子pid为%d\n”,子pid);
}
}
killpg(getpid(),SIGTERM);
printf(“p2终止。\n”);
出口(0);
}
int解析(char*commandLine,char*argv[]){
int argc=0;
char*commandPointer=commandLine;
而(*commandPointer!='\0'){
*argv=命令指针;
argc++;
getword(命令指针);
}
*commandPointer='\0';
*argv='\0';
返回argc;
}

提示:您的解析函数应该从s填充argv,可能对每个条目使用strdup,那么您的execvp应该看起来像execvp(argv[0],argv);。请注意,从scanf扫描的字符串永远不会包含EOF。在上面的注释中,我应该说“strtok和strdup”不仅仅是strdupshould我的解析函数然后返回char**?还是它也在解析函数之外被填充?奇怪的是,这是要求您从主函数内部填充
*argv[]
,还是可以从命令行与argc一起填充它?如果您需要在main()中填充它的话,那么我相信您首先需要进行一些内存分配。如果以传统方式使用,则在从命令行读取参数时,主函数定义会为您处理此问题。进行了彻底的检查,现在argv似乎充满了参数。我尝试发布更新的代码作为答案,但我无法再等待5小时我们的,因为我没有足够的声誉!我会在晚上把它发回。@Ryker我想用argv[]来执行命令,我现在正在做。我用你的for循环的想法来打印*argv[]的内容,似乎正按照我的要求工作