在以下代码中:
#include <stdio.h>
#include <string.h>
int main (int argc, const char * argv[]) {
char input[20];
fgets(input, sizeof(input), stdin);
char * pch;
pch = strtok(input, " ");
int i = 0;
int nums[3];
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok(NULL, " ");
//nums[i] = atoi(pch);
i++;
}
return 0;
}
输入
1 2 3
给出:
1
2
3
当我取消注释注释行时,我得到:
1
2
3
Segmentation fault: 11
为什么这一行导致seg错误?
答案 0 :(得分:5)
主要的是您需要在再次呼叫atoi(pch)
之前运行strtok
:
printf ("%s\n",pch);
nums[i++] = atoi(pch);
pch = strtok(NULL, " ");
否则,对atoi
的最后一次调用会将空指针作为参数传递,atoi
崩溃。
感兴趣的另一个细节是input
最后可能包含换行符。这对于atoi
来说不是问题,但它会导致循环迭代4次并在nums
结束后写入。虽然它很可能不会导致程序崩溃,但这仍然是未定义的行为,您应该插入数组边界检查以防止它。
答案 1 :(得分:3)
调试代码以使其正确且健壮。
if (i >= 0 && i < 3)
{
// The value of i is a Valid index for "int nums[3];"
nums[i] = atoi(pch);
}
else
{
// The value of i is NOT a Valid index for "int nums[3];", so why even try?
// Using "nums[i]" here would cause undefined behaviour.
}
int currentInt = atoi(pch);
nums[i] = currentInt;
其中哪一条线路正在崩溃?
如果是第二个,你应该能够通过我建议的范围检查来阻止它。
如果它是第一个,int currentInt = atoi(pch);,则意味着atoi正在崩溃,因为它的返回值正好是int,所以将结果赋给currentInt是安全的。
为什么atoi会崩溃?现在你已经缩小了你的问题范围。继续缩小范围,直到找到它为止。
答案 2 :(得分:1)
保持换行
变化
pch = strtok(NULL, " ");
到
pch = strtok(NULL, " \n");
答案 3 :(得分:1)
你必须检查strtok的返回(如果没有更多令牌则返回NULL)并检查i,因为这个var不能达到3,因为nums数组只分配给3个int。
while (pch != NULL && i < 3)
{
printf ("%s\n",pch);
pch = strtok(NULL, " ");
if (pch != NULL)
nums[i] = atoi(pch);
i++;
}
答案 4 :(得分:0)
因为你在数组边界之外循环
int i = 0;
int nums[3];
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok(NULL, " ");
nums[i] = atoi(pch); // i == 3 will cause the issue
i++;
}
而不是尝试
int i = 0;
int nums[3];
for (pch = strtok(input, " "); pch != NULL && i < 3; pch = strtok(NULL," "))
{
printf ("%s\n",pch);
nums[i++] = atoi(pch);
}
答案 5 :(得分:0)
使用strtok
每次获得一个字符并将其放入数组中
但是,strtok
在分隔符或字符串结尾之前返回字符串
对于最后一个值,即3
,它还附加了\n
,并且您尝试将其作为单个字符添加。
在获取下一个
之前,只需将值放入数组即可int i = 0;
int nums[3];
while (pch != NULL)
{
printf ("%s\n",pch);
nums[i] = atoi(pch);
pch = strtok(NULL, " ");
i++;
}
/*// Testing the array
for(i = 0; i< 3; i++)
printf("%d ",nums[i]);
*/