【发布时间】: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, &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,您的比较器功能可以快速轻松地发挥作用。你可能会侥幸逃脱,但你不应该试图这样做。