【问题标题】:Qsort removing elementsQsort 删除元素
【发布时间】:2018-01-27 22:34:15
【问题描述】:

我正在尝试使用 qsort 对结构数组进行排序,但是当我显示排序后的结构时,除了一个之外,其他所有结构都丢失了。

以下是我的代码的相关部分:

typedef struct {
    char firstName[20];
    char lastName[20];
    float height;
} myStruct;

....

 else if (argc > 2) {
            FILE * inf;
            inf = fopen(argv[2], "r");
            errorCheck(fscanf(inf, "%d", &numStructs));
            people = (myStruct*)malloc(sizeof(myStruct) * numStructs);
            for (int i = 0; i < numStructs; ++i) {
                    errorCheck(fscanf(inf, "%s %s %f", firstName, lastName, &height));
                    person = people + (sizeof(myStruct) * i);
                    initMyStruct(person, firstName, lastName, height);
            }
            printf("struct read in");
    }

...

    if (strcmp(argv[1], "last") == 0) {
            fprintf(stdout, "last name sort if statement, \n");
            //myStruct* person = people + (sizeof(myStruct));
            qsort(people, numStructs, sizeof(myStruct), lastCmp);
    }
    else {
            fprintf(stdout, "height sort if statement, \n");
            //myStruct* person = people + (sizeof(myStruct));
            qsort(people, numStructs, sizeof(myStruct), heightCmp);
    }

还有我的比较函数

int lastCmp(const void *a, const void *b) {
        myStruct* c = (myStruct *)a;
        myStruct* d = (myStruct *)b;
        return(strcmp(c->lastName, d->lastName));
}

int heightCmp(const void* a, const void* b) {
        myStruct *personA = (myStruct *)a;
        myStruct *personB = (myStruct *)b;
        return((personA->height > personB->height) - (personB->height > personA->height));
}

这是输出:

First name: Abigail, last name: Egan, height: 5.300000, 
First name: Jim, last name: Gardner, height: 5.500000,
First name: Jenna, last name: Adams, height: 5.500000,
First name: Maggie, last name: Johnson, height: 4.900000,
First name: Chelsea, last name: Harrison, height: 5.400000,
First name: Anna, last name: DeHart, height: 5.000000,

First name: , last name: , height: 0.000000,
First name: , last name: , height: 0.000000,
First name: , last name: , height: 0.000000,
First name: , last name: , height: 0.000000,
First name: , last name: , height: 0.000000,
First name: Abigail, last name: Egan, height: 5.300000,

(对于可读性,我很抱歉,格式没有保留。)如果您需要查看我的代码的其他部分,请告诉我。第一个输出是读入后立即显示的结构数组。第二个输出是排序后的。我需要继续使用 qsort,我不能使用其他方法。

【问题讨论】:

  • "如果您需要查看我的代码的其他部分,请告诉我" - 这不是它的工作原理。发布minimal reproducible example
  • person = people + (sizeof(myStruct) * i); 具有未定义的行为。
  • 旁白:errorCheck(fscanf(inf, "%s %s %f", firstName, lastName, &amp;height)); errorCheck 如何知道应该输入多少个值(这里是 3)?这是scanf 函数族的基本检查,它也将捕获EOF。理想情况下,检查EOF,但没有输入可以信任,所以检查转换的项目数。
  • people + (sizeof(myStruct) * i); like melpomene 说它是 UB。在进行指针运算时,您不必担心结构的大小,这是编译器的工作。 people + i 将完成这项工作。
  • qsort(people, numStructs, sizeof(myStruct), lastCmp);qsort((void *)people, numStructs, sizeof(myStruct), heightCmp); 之间的差异令人费解。可能没有害处,但为什么不一致。您不显示打印代码。这不是一个连贯的 MCVE (minimal reproducible example)。使用const-ness,您的比较器功能可以快速轻松地发挥作用。你可能会侥幸逃脱,但你不应该试图这样做。

标签: c qsort


【解决方案1】:

无法可靠地分析您的问题,因为您没有发布实际源代码以获得最小、完整且可验证的示例。您还需要将输入的内容发布到程序中。

我将对观察到的行为进行潜在的解释:

  • 您对fscanf() 成功的测试不正确:针对EOF 的测试不充分,您必须检查fscanf() 是否转换了3 个输入并返回3。不正确的输入将导致fscanf() 返回一个短计数,并且后续调用将忽略输入,从而使您的变量处于不一致的状态。

  • 不正确的输入例如Michael J Fox 5.2:firstName 将得到Michael,lastName 将得到Jheight 的转换将失败。后续调用会消耗不同步的输入流...

【讨论】:

  • 我知道这些潜在的错误,并且我知道它们都不会导致这个问题。我的 errorCheck 函数检查以确保 fscanf() 返回正确的数字。我有理由相信该错误存在于我传递给 qsort 或比较函数中。
  • 您不知道是什么导致了问题。提供的输出可能表明您正在排序的元素多于读入数组的元素,这可以通过解析阶段的问题来解释。微妙的问题可以隐藏在看似无辜的 C 代码中,发布一个完整的示例以及实际输入是在 stackoverflow 上获得正确答案的最佳方式。
猜你喜欢
  • 2020-05-09
  • 2013-07-18
  • 1970-01-01
  • 2017-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-14
相关资源
最近更新 更多