0

我遇到了这个 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);
}
4

1 回答 1

1

外循环应遍历 的所有条目ary,因此结束条件应测试是否walker为 (at) end

这里不需要取消引用:

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

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

compare < walker;

应该

compare < (walker - ary);

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

因此compare应声明:

ptrdiff_t compare;

strcmp()0如果要比较的字符串相等则返回,因此设置diff为不相等0是错误的。

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

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

如果两个字符串相等(不是 *diff*erent),则设置diff0(false)。

发现欺骗后也应停止比较。

    if (!diff)
    {
      break;
    }

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


代替

    strncpy(*walker, fullname, strsize);

    *walker = fullname;

asfullname指的是新分配的内存,需要存储,在下一次迭代中被覆盖。

线条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);
    }
  }
} 
于 2013-08-04T11:17:51.880 回答