【问题标题】:Cannot loop through array of strings after qsort()在 qsort() 之后无法循环遍历字符串数组
【发布时间】:2021-11-27 16:49:17
【问题描述】:

我正因为这个问题把头撞到墙上。

总结一下: 我需要动态地将字符串添加到数组中,对它们进行排序,然后检查另一个字符串值。

这需要在支持 C 作为脚本语言但功能有限的 SCADA 系统上工作。我有 qsort() 可用。

但是,使用我拥有的测试代码,我无法在数组上使用 qsort,其值是动态添加的。

为了清楚起见,我可以将字符串添加到数组中,效果很好。 但是,当我在该数组上调用 qsort() 时,我无法再打印出索引。

这是目前的代码(请客气,我对 C 语言不是很精通):

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int cstring_cmp (const void *a, const void *b)
{
  // This function is taken from an online example
  const char **ia = (const char **) a;
  const char **ib = (const char **) b;
  return strcmp (*ia, *ib);
}


int main ()
{
  //char *ArchiveKomponents[] = {"R1890L", "F1121D", "F1284Z", "A1238K"};
  // If I do the above commented out, it works as intended
  char ArchiveKomponents[100][20];

  strcpy(ArchiveKomponents[0], "R1890L");
  strcpy(ArchiveKomponents[1], "F1284Z");

  size_t strLen = sizeof (ArchiveKomponents) / sizeof (char *);
  printf ("Len: %zu\n", strLen);

  printf ("Before [0]: %s\n", ArchiveKomponents[0]);
  printf ("Before [1]: %s\n", ArchiveKomponents[1]);

  qsort (ArchiveKomponents, (size_t)strLen, sizeof (char *), cstring_cmp);

  printf ("After [0]: %s\n", ArchiveKomponents[0]);
  printf ("After [1]: %s\n", ArchiveKomponents[1]);
  
  // When run, the "After" prints are not even printed, the program simply halts
  
  return 0;
}

我觉得我已经用谷歌搜索了整个互联网,以寻找有关如何做到这一点的答案,但没有运气。

问候

【问题讨论】:

  • 你需要比较char[20]而不是char*
  • 为什么要对整个数组进行排序?你只初始化了两个元素!
  • @MartinJames 我本来可以更清楚的,我的错。在这个测试中,我只尝试了 2 个元素,但最后我可能需要使用多达 100 个元素,因此数组的大小为 100。在数组声明上方的注释行中,您将看到 4 个元素

标签: arrays c string qsort wincc


【解决方案1】:

您正在比较不正确的类型。比较函数将元素中的 4 或 8 个字符视为指向字符串的指针。取消引用此指针会触发未定义行为,可能会导致崩溃。

注意,单个元素的类型是char[20] 而不是char*。因此,您的比较功能可以简单地实现为:

int cstring_cmp (const void *a, const void *b)
{
  return strcmp (a, b);
}

指针 ab 指向 到 20 个字符的数组。数组的地址与其第一个元素的地址相同。所以ab 可以用作指向char 链的指针(又名“c-strings”)。 此外,void* 会自动转换为任何指针类型而无需强制转换。

qsort 调用应该是:

qsort (ArchiveKomponents,           // array to be sorted
       2,                           // number of elements in the array
       sizeof ArchiveKomponents[0], // size of a single element
       cstring_cmp                  // comparison function 
);

【讨论】:

  • 还提到strLen 计算不正确:而不是size_t strLen = sizeof (ArchiveKomponents) / sizeof (char *);,它应该是size_t strLen = sizeof (ArchiveKomponents) / sizeof (ArchiveKomponents[0]);,同样非常令人困惑。无论如何,使用活动条目的数量要好得多。
  • @chqrlie,对,但是问题中有效元素的数量是 2
  • 确实,使用活动条目的数量无论如何要好得多。
猜你喜欢
  • 2023-03-23
  • 2017-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-16
  • 2019-09-07
相关资源
最近更新 更多