【问题标题】:Sorting an array of pointers to struct inside another struct对指向另一个结构内的结构的指针数组进行排序
【发布时间】:2021-06-20 23:48:01
【问题描述】:

我有两个结构, 第一个看起来像这样:

typedef struct plant
{
  char ID[10];

  char scientific_name[MAX_NAME];

  char **alias;

  int n_alias;

  int n_seeds;

} plant;

第二个本质上是一个成员数组

typedef struct catalog
{
  plant **plants;

  long catalog_size;
 /*specifies if the plants array is either sorted by ID or scientific_name*/
  char ordering_method[5];

} catalog;

我尝试使用 qsort 对目录中的 **plants 数组进行排序,我的函数调用如下:

int catalog_sort(catalog *c, const char *ordering_method)
{
    if (!strcasecmp(ordering_method, "ID"))
        qsort(c->plants, c->catalog_size, sizeof(plant *), qsortKey_ID);
    else if (!strcasecmp(ordering_method, "name"))
        qsort(c->plants, c->catalog_size, sizeof(plant *), qsortKey_name);
    else
        return -1;

    return 0;
}

两个 qsortKey_ 函数的工作原理基本相同,但比较结构的不同元素

int qsortKey_ID(const void *a, const void *b)
{
    const plant *pa = (plant *)a;
    const plant *pb = (plant *)b;

    /*checking to see if data is corrupted when the fuction gets called*/
    printf("ID A - %s, ID B - %s, COMP: %d\n", pa->ID, pb->ID, strcmp(pa->ID, pb->ID));

    return strcmp(pa->ID, pb->ID);
}

当我运行此代码时,qsort 无法正常工作,无法对数组进行排序,并且 valgrind 在两个 qsortKey_ 函数进行的 strcmp 函数调用中都出现“无效的读取大小为 1”,这符合事实上面的prinf打印的数据确实被破坏了,有趣的是,数组本身之后很好,只是没有正确排序。

我已经为此苦苦挣扎了一段时间,但无济于事,因此感谢您提供任何意见。这不是qort的正确应用吗?我应该求助于手动实现排序算法吗?

【问题讨论】:

  • 为什么将plant指针作为void指针传递给函数qsortKey_ID
  • 嗯...我可以理解您的目录中有一个指向植物的指针数组。本身不是问题,但魔鬼经常隐藏细节。您能否提供minimal reproducible example 来展示您如何构建最小目录并尝试对其进行排序。
  • @AndySukowski-Bang 据我所知,qsort 比较函数需要 const void * 作为参数,否则不能作为参数传递。
  • @SergeBallesta 我正在做一个例子,但与此同时我的问题得到了成功的回答,所以不再需要了,无论如何谢谢。

标签: arrays c sorting struct qsort


【解决方案1】:

你缺少一个间接。

比较函数接受两个指向数组元素的参数,因此:

int qsortKey_ID(const void *a, const void *b)
{
    const plant *pa = *(plant **)a; // a == &plants[some index]
    const plant *pb = *(plant **)b; // b == &plants[some other index]

    /*checking to see if data is corrupted when the fuction gets called*/
    printf("ID A - %s, ID B - %s, COMP: %d\n", pa->ID, pb->ID, strcmp(pa->ID, pb->ID));

    return strcmp(pa->ID, pb->ID);
}

注意额外的星号。

【讨论】:

  • 解决了,谢谢!我想我需要更加小心 qsort 如何将数据传递给比较函数。
  • @TiagoAmorim 或使用 C++ :P
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-11
  • 2017-07-13
  • 2020-03-15
相关资源
最近更新 更多