不明白为什么C程序崩溃,指针数组的字符串

时间:2013-08-04 04:26:00

标签: c arrays string pointers for-loop

我遇到了这个for循环的麻烦,我不明白为什么它会崩溃。我正在尝试以“名字姓氏”格式读取20个名字的输入列表,并将它们存储为“姓氏,名字”中的字符串。不应将重复项存储到数组指针中。

当我注释掉malloc并比较循环时,显然地址保持不变存在一些问题,因此* ary返回与* walker相同的值。 filePtr有效,strcpy和strcat函数没有问题。此外,删除第一个printf也会导致程序崩溃,即使删除它似乎不会产生除输出之外的任何实际效果。

FILE *filePtr = fopen ("input.txt","r");
int size = 20;
char **ary;
char **walker;
char **end;
int strsize = 0;
char firstname[30] = {0};
char lastname[30] = {0};
char *fullname;
ary = calloc (size, sizeof(char *));
printf("%d\n",sizeof(pAry));
for ( walker = ary ; *walker < (*end = *ary + size) ; walker++)
{
    fscanf(filePtr," %s",firstname);
    fscanf(filePtr," %[^\n]",lastname);
    strsize = strlen(firstname) + strlen(lastname) + 3;
    fullname = malloc (strsize * sizeof(char));
    strcpy(fullname,lastname);
    strcat(fullname,", ");
    strcat(fullname,firstname);
    for ( compare = 0 ; compare < walker ; compare++)
    {
        if(strcmp(fullname,*(ary + compare)) != 0)
        {
            diff = 0;
        }
    }
    if (diff)
    {
        strncpy(*walker,fullname,strsize);
        printf("%s\n",*walker);
    }
    free(fullname);
}

1 个答案:

答案 0 :(得分:1)

外部循环应循环遍历ary的所有条目,因此结束条件应测试walker的{​​{1}}是否为end

此处不需要取消引用:

for (walker = ary; walker < (end = ary + size); walker++)

重复项的测试循环确实比较了绝对指针值,compare0的初始化意味着相对比较所以这一行

compare < walker;

应该是

compare < (walker - ary);

提取两个指针会返回一个整数,其大小取决于指针的大小,这取决于编译器和/或系统。为了解决这种不确定性,引入了整数类型ptrdiff_t以确保保持任何指针差异。

所以compare应声明:

ptrdiff_t compare;

如果要比较的字符串相同,

strcmp()会返回0,因此将diff设置为0的不等式是错误的。

您可能希望使用以下语句来设置diff

    diff = strcmp(fullname,*(ary + compare));

如果两个字符串相等(不是* diff * erent),这会将diff设置为0(false)。

在发现死刑后,也应停止比较。

    if (!diff)
    {
      break;
    }

最后,每次迭代都需要(重新)初始化diff


而不是

    strncpy(*walker, fullname, strsize);

DO

    *walker = fullname;

as fullname引用新分配的内存并需要存储,在下一次迭代中被覆盖。

free()fullname

  free(fullname);

需要删除。


把所有这些放在一起你得到:

...

for (walker = ary; walker < (end = ary + size); walker++)
{
  ...

  {
    int diff = 1;
    for (ptrdiff_t compare = 0; compare < (walker - ary); compare++)
    {
      diff = strcmp(fullname, *(ary + compare));       
      if (!diff)
      {
        break;
      }
    }

    if (diff)
    {
      *walker = fullname;
      printf("%s\n", *walker);
    }
  }
}