这是代码,当输入“历史1”时,它应该在history
中执行第一个命令:
#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
)地址越界和 - 访问冲突(分段错误)。您可以在下面的图片中看到错误。
我错过了什么?我做错了什么?
答案 0 :(得分:1)
您正在处理分段错误的原因是您尝试将字符串复制到尚未分配的内存中。您已将result
定义为char*
,并为其分配了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]);
}
答案 1 :(得分:1)
您可能意味着char tokenArray[100][100];
会在1个令牌中创建100
tokens
个100
个字符。
写char *tokenArray[100][100]
字面意思是tokenArray
是100
数组的数组,其中包含100
char *
。但是,如果没有为其分配正确的地址,则char *
中的每一个都指向一个随机地址。
您收到分段违规错误,因为其中一个char *
包含您无法访问的地址。