我的程序的这一部分旨在迭代字符串的char
,并选择字符串中的所有数字并将它们放在一个名为helper
的数组中。这是我正在处理的大型程序的一小部分,我尽力只提供有用的代码段。我也知道如何正确使用指针时出现分段错误,但我的问题是我无法找到错误使用指针的位置。
因此,当我尝试编译以下代码时,我收到 Segmentation fault(core dumped) ...
#include <stdio.h>
#include <string.h>
int main(void)
{
char *eq = "y=344+99";
int helper[50];
unsigned short int helperWriter = 0, i;
for (i = 0; i < eq[i]; i++) //
{
if (isdigit(eq[i]))
{
unsigned short int d;
for (d = i; eq[d]; d++)
{
if (isdigit(eq[d]))
{
int temp = atoi(eq[d]);
helper[helperWriter] = temp;
printf("%d", helperWriter);
}
helperWriter++;
}
}
}
}
我对C来说相当新,反过来,对指针来说是新手,所以我的错误可能相当愚蠢。如果需要任何额外信息,请询问。
答案 0 :(得分:3)
当您使用库函数而不包含其原型时,编译器会假设其参数和返回类型为int
。你没有#include <stdlib.h>
(或ctype.h
),所以在这一行中
int temp = atoi(eq[d]);
您正在传递char
,编译器乐意将其提升为int
。但atoi
需要char*
类型。因此它尝试访问机器中低地址的内存,导致段错误。该行应
int temp = atoi(eq + d); // or `atoi(&eq[d])`
将每个字符串字符的地址传递给atoi
。
第一个循环不正确,您应该测试nul
终结符。
如果helperWriter++;
位置错误,您也会遇到错误:将其移至您将temp
放入数组的下方。
您还忽略了我的建议,即在每条调试消息的末尾添加newline
(以确保在崩溃发生之前实际看到它)。
您获取号码然后移过它的方式可能还有其他错误。您不需要两个嵌套循环,atoi
会将数字转换为下一个非数字字符。
答案 1 :(得分:2)
由于@Weather Vane指出了代码中的问题,我想向您展示另一种解决方案:
#include <stdio.h> /* printf */
#include <string.h> /* strcspn */
#include <stdlib.h> /* strtol */
int main(void)
{
char *eq = "y=344+99", *ptr = eq;
int helper[50];
size_t i = 0;
while(*ptr) // Is there any more numbers in the string?
{
ptr += strcspn(ptr, "1234567890"); // Move ptr to the next number
helper[i++] = strtol(ptr, &ptr, 10);
printf("%d\n", helper[i - 1]);
}
}
虽然这段代码看起来有点复杂,但它更紧凑,它利用了库函数,使其更有效。