通过引用传递数组

时间:2011-01-31 03:04:27

标签: c arrays

我无法弄清楚我在哪里搞砸了。我传递了一系列字符指针。在函数内部我试图使用strtok将字符串分解为更小的片段以分配给char *数组。我可以尝试在功能中打印它,它们都正确显示。一旦我尝试将它打印回主体,我就会得到垃圾。

#include <stdio.h>
#include <string.h>

#define CMDLEN 100
#define MAXARG 5
void prompt();
int getCommand (char* cmdAndParameters[]);

int main() {
     int numArgs = 0;
     char* cmdAndParameters [MAXARG];

     while (true){
          prompt ();
          numArgs = getCommand (cmdAndParameters);
     }
}

void prompt() {
     printf("shell> ");
}

int getCommand(char* cmdAndParameters[]){
     int argNum = 0;
     bool foundArg = true;
     char* delimiters = " \t\n";
     char userRequest[CMDLEN];

     fgets(userRequest,sizeof(userRequest), stdin); 

     if ((cmdAndParameters[argNum] = strtok(userRequest, delimiters)) != NULL)
     {  
          argNum++;

          for (; argNum < MAXARG && foundArg; argNum++) {
               if ((cmdAndParameters[argNum] = strtok(NULL,delimiters))
                         == NULL) 
               {
                    foundArg = false;
               }
               // merely to test output remove later
               else {printf("%s\n", cmdAndParameters[argNum]);}
          } 

     }

     return argNum;
}

2 个答案:

答案 0 :(得分:4)

在这种情况下,你的内部字符数组被分配为“自动”,也就是说,在堆栈上。当你执行strtok时,你将指定一个指向堆栈上分配的内存的指针,然后返回 - 这意味着不再分配内存。

将userRequest数组移动到文件范围内(即在块外)或使分配“静态”,你将获得更好的镜头。

<强>更新

嗯,这比现在多一点,现在再看一遍。

首先,如果使用while循环(例如

),可以大大清理它
argNum = 0;
while((cmdAndParameters[argNum++] = strtok(userRequest, delimiters)) != NULL)
    ;  /* all the work is happening in the conditional part of the while */

甚至是for循环

for(argNum = 0; 
    (cmdAndParameters[argNum] = strtok(userRequest, delimiters)) != NULL);
    argNum++)
    ; /* still all the work is in the for */

现在如果argNum > 0你知道你找到了什么。

其次,您需要考虑如何以及何时分配内存。你的cmdAndParameters阵列是在main启动时分配的(在堆栈上,它是“自动的”)所以只要你的程序存在,你就可以了。但是您的userRequest数组已在getCommand中自动分配;当getCommand返回时,内存被释放;堆栈指针向后移动,你不再保证。所以当你执行strtok时,你会将指针保存到堆栈中,这可能会导致无效。

答案 1 :(得分:0)

你想要吗

for (; argNum < MAXARG && foundArg; argNum++)

或类似

for(argCntr = argNum; argCntr < MAXARG && foundArg; argCntr++)

希望有所帮助。