0

这是代码,它应该在history输入“history 1”时执行第一个命令:

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

int main (int argc, char *argv[])
{
    int i=0; int j=0; int k=0;
    char inputString[100];
    char *result=NULL;
    char delims[] = " ";
    char historyArray[100][100] = {0};
    char *tokenArray[100][100] ;

    do
    {
        j = 0;
        printf("hshell>");
        gets(inputString);
        strcpy (historyArray[k], inputString);
        k++;

        // Break the string into parts
        result = strtok(inputString, delims);

        while (result!=NULL)
        {
            //result2 = result;
            strcpy(tokenArray[j], result);
            //puts(result);
            j++;
            result= strtok(NULL, delims);                  
            //puts(tokenArray[j]);     
        }
        //j = 0;
        puts(tokenArray[0]);
        puts(tokenArray[1]);

        if (strcmp(tokenArray[0], "exit") == 0)
        {
            return 0;
        }
        else if (strcmp(tokenArray[0], "history") ==  0)
        {
           if (j>1)
           {
              strcpy (result,historyArray[atoi(tokenArray[j-1])]);

           }
           else
           {
               //print history array
               for (i=0; i<k;i++)
                   printf("%i. %s\n", i+1, historyArray[i]);
           }
        }
        else
        {
          printf("Command not found\n");
        }
    }while (1);
}

但是,它崩溃了。在调试时,我注意到两件事: - 数组 ( tokenArray) 地址超出范围和 -访问冲突(分段错误)。您可以在下图中看到错误。

越界

分段故障

我错过了什么?我究竟做错了什么?

4

2 回答 2

1

您处理分段错误的原因是因为您试图将字符串复制到尚未分配的内存中。您已定义result为 achar*并刚刚分配NULL给它,因此尝试将字符串复制到其中是错误的:

char *result = NULL;
// ...
strcpy(result, historyArray[atoi(tokenArray[j-1])]);

您需要分配一些内存,这result将指向。然后strcpy可用于将字符串复制到此内存中。您可以使用malloc动态分配它,也可以将其定义result为具有自动存储持续时间的临时变量(即char result[100];)。


另请注意

char *tokenArray[100][100];

定义指向 的指针的二维数组char。但是在这种情况下你真正需要的是一个字符串数组,所以你需要*像@cnicutar 指出的那样摆脱。


还有一个注意事项:

strcpy(result,historyArray[atoi(tokenArray[j-1])]);

这样做是非常危险的,因为当atoi失败时,您试图访问数组边界之外的元素,这会产生未定义的行为,因此我建议您执行以下操作:

char tokenArray[100][100] = {0};

int index;
char indexString[100] = "8";
if (sscanf(indexString, "%d", &index) == 1)     // integer successfully retrieved
{
    strcpy(tokenArray[index], "some string");
    printf("%s", tokenArray[8]);
}
于 2013-02-24T13:36:39.020 回答
1

您可能的意思是使用1 个令牌中的每个字符char tokenArray[100][100];创建。100 tokens100

字面char *tokenArray[100][100]意思tokenArray是一个数组100数组,其中包含100 char *. 但是,如果没有为其分配正确的地址,则这些地址中的每一个都char *指向随机地址。

您收到分段违规错误,因为其中一个char *包含您无法访问的地址。

于 2013-02-24T14:42:45.617 回答