1

我遇到了一些麻烦,因为我是 C 新手,甚至不确定我想做的事情是否可行。

我将一个名为args的数组传递给一个函数。在函数中,我还创建了一个名为arrayOfArgs的二维数组。我想要做的是将 args 中的某些值放入名为 arrayOfArgs 的二维数组中的特定位置。

到目前为止,这是我的代码:

int do_command(char **args){
        //this is usually a changing variable depending on the situation, but I've hard coded it to make sense
        int commands = 3;
        char **arrayOfArgs[commands][10];
        //counts which column in arrayOfArgs we are on
        int commandNum = 0;

//Counts which part of a command we are on
        int count = 0;

    //Array Counters
    int i = 0;
    int j;

    //Go through args until we reach the end
    while (args[i] != NULL){
        if(!strcmp(args[i], "|")){
            arrayOfArgs[commandNum][count] = args[i];
            count++;
        }
        else if (strcmp(args[i], "|")) {
            count = 0;
            commandNum++;
        }
        //Looking at the next value in args
        i++;
    }

我遇到了问题,因为放入 arrayOfArgs 的唯一内容是胡言乱语。我确定我在数组指向的方式、arrayOfArgs 的创建方式或两者上都做错了。

或者是否有可能像我正在尝试的那样从一维数组变为二维数组?

我很确定那里有一个 NULL 因为之前我调用了这个循环并且它有效:

for(i = 0; args[i] != NULL; i++) {
    printf("Argument %d: %s\n", i, args[i]);
}

谢谢!

4

4 回答 4

1

首先,您如何验证的内容arrayOfArgs是乱码?你用 打印出内容printf吗?你在使用调试器吗?

其次,每个元素arrayOfArgs应该存储什么?它应该是一个由 9 个字符或更少字符组成的 3 元素数组吗?它应该是一个 3x10 元素的指针数组char吗?它应该是指向指针的 3x10 元素数组char吗?

在行

 arrayOfArgs[commandNum][count] = args[i];

表达式args[i]有类型char *;这强烈暗示您打算为 的每个元素arrayOfArgs存储一个char *. 在这种情况下,将声明更改arrayOfArgs

char *arrayOfArgs[commands][10];

(我读到这个是因为每个命令最多可以有 9 个参数)。

IOW,看起来你正在尝试存储类似的东西

    列 0 1 2 3 4 5 6 7 8 9
排
  0 "cmd" "a1" "a2" NULL NULL NULL ...
  1 "cmd" "a1" 空
...

通过存储指向二维数组中每个字符串的指针。

如果是这种情况,那么您需要更改arrayOfArgs我上面所说的声明。如果不是这样,那么你需要给我们一个应该arrayOfArgs是什么样子的例子。

于 2012-09-24T22:10:22.967 回答
0

问题在这里:

char **arrayOfArgs[commands][10];

这声明了一个双字符指针的二维数组,这不是您想要的。

请尝试以下操作:

char *arrayOfArgs[commands][10];

编辑:更改为char*因为在检查代码后我发现 OP 将指向字符数组的指针分配给arrayOfArgs. 感谢@wildplasser 的通知。

于 2012-09-24T22:00:22.953 回答
0

所以我看到了一些问题......

首先我相信你的意思char arrayOfArgs[commands][10];是你想要一个 10 个字符串的二维数组(我假设这是你想要的)......否则它将是一个字符串指针数组的二维数组(就像一个 4D 字符数组:P)

|接下来,如果参数本身是,您创建的代码只会将字符复制到每个命令缓冲区中|

如果您正在查找管道符号之间的内容,请查看函数strchr,并且strncpy使用这些函数,我将遍历每个 arg,如果和参数是管道符号|,找到带有管道符号的下一个参数,循环遍历中的参数之间,然后将中间的字符复制到动态分配的字符数组中

此外,在您的评论中,您说命令数组将是动态的......您的程序结构化数据的方式是静态分配在堆栈上的。要使这种动态化,您需要动态分配到堆上,即malloc/calloc

于 2012-09-24T22:11:29.533 回答
0

我想到了。我决定采用 1D 阵列路线而不是 2D 方式。代码现在采用 args,之前被拆分为 "ls" "-l" "|" “wc”并根据是否有管道将它们分隔到一个名为“arrayOfCommands”的新数组中。一旦完成,arrayOfCommands 的内容就是“ls -l”和“wc”。这是代码:

int do_command(char **args,) {
    const int commands = 2;
    int i = 0;

    int commandNum = 0;
    int firstCommand = 1;

    char *arrayOfCommands[commands];

    //Go through args until we reach the end
    while (args[i] != NULL){
        //First case            
        if(firstCommand){
            arrayOfCommands[commandNum] = args[i];
            firstCommand = 0;
        }
        //Rest of the cases
        else{
            //if we find something that's not a pipe...
            if(strcmp(args[i], "|")){
                //Add a space to what was a previous part of the same command
                arrayOfCommands[commandNum] = strcat(arrayOfCommands[commandNum]," ");
                arrayOfCommands[commandNum] = strcat(arrayOfCommands[commandNum],args[i]);
            }
            //But if we do find a pipe...
            else if (!strcmp(args[i], "|")) {
                //We know it's time for a new command
                commandNum++;
                firstCommand = 1;
            }               
        }
        //Looking at the next value in args
        i++;
    }

    for(i = 0; i < commands; i++)
        printf("Command #[%d]: %s\n", i, arrayOfCommands[i]);
}
于 2012-09-26T21:57:23.070 回答