qsort 不排序并且输出奇怪
所以我正在使用C,我似乎无法让它正常工作。它是一个指向包含一些联系信息的结构的指针数组。我似乎无法让 qsort 正确排序。 这是我的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20
#define ELEMENTS 50
int sortZips(const void *a, const void *b);
typedef struct contactInfo {
char name[MAX];
char street[MAX];
char cityState[MAX];
char zipCode[MAX];
} contacts;
int main() {
int i = 0;
contacts **contactArray = malloc(ELEMENTS * sizeof(contacts *));
/* allocate array */
for (i = 0; i < ELEMENTS; i++) {
contactArray[i] = malloc(sizeof(contacts));
}
/* populate array */
for (i = 0; i < ELEMENTS; i++) {
fgets(contactArray[i]->name,MAX,stdin);
fgets(contactArray[i]->street,MAX,stdin);
fgets(contactArray[i]->cityState,MAX,stdin);
fgets(contactArray[i]->zipCode,MAX,stdin);
printf("%s", contactArray[i]->name);
printf("%s", contactArray[i]->street);
printf("%s", contactArray[i]->cityState);
printf("%s", contactArray[i]->zipCode);
}
printf("\n");
/* qsort((void *)contactArray, ELEMENTS, sizeof(contacts *), sortZips); */
for (i = 0; i < ELEMENTS; i++) {
fputs(contactArray[i]->name,stdout);
fputs(contactArray[i]->street,stdout);
fputs(contactArray[i]->cityState,stdout);
fputs(contactArray[i]->zipCode,stdout);
}
}
/* sortZips() sort function for qsort */
int sortZips(const void *a, const void *b) {
const contacts *ia = *(contacts **)a;
const contacts *ib = *(contacts **)b;
return strcmp(ia->zipCode, ib->zipCode);
}
输出是打印地址(我在输入文件中有 50 个),然后是一些随机字符,比如一大块,然后是排序后的列表,该列表混乱且排序不正确。
请提供任何帮助,我们将不胜感激。我需要了解这里出了什么问题以及原因。 谢谢。
so I'm using C, I cant seem to get this to work right. It's an array of pointers to structs which contain some contact info. I can't seem to get the qsort to sort correctly.
Here is my code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20
#define ELEMENTS 50
int sortZips(const void *a, const void *b);
typedef struct contactInfo {
char name[MAX];
char street[MAX];
char cityState[MAX];
char zipCode[MAX];
} contacts;
int main() {
int i = 0;
contacts **contactArray = malloc(ELEMENTS * sizeof(contacts *));
/* allocate array */
for (i = 0; i < ELEMENTS; i++) {
contactArray[i] = malloc(sizeof(contacts));
}
/* populate array */
for (i = 0; i < ELEMENTS; i++) {
fgets(contactArray[i]->name,MAX,stdin);
fgets(contactArray[i]->street,MAX,stdin);
fgets(contactArray[i]->cityState,MAX,stdin);
fgets(contactArray[i]->zipCode,MAX,stdin);
printf("%s", contactArray[i]->name);
printf("%s", contactArray[i]->street);
printf("%s", contactArray[i]->cityState);
printf("%s", contactArray[i]->zipCode);
}
printf("\n");
/* qsort((void *)contactArray, ELEMENTS, sizeof(contacts *), sortZips); */
for (i = 0; i < ELEMENTS; i++) {
fputs(contactArray[i]->name,stdout);
fputs(contactArray[i]->street,stdout);
fputs(contactArray[i]->cityState,stdout);
fputs(contactArray[i]->zipCode,stdout);
}
}
/* sortZips() sort function for qsort */
int sortZips(const void *a, const void *b) {
const contacts *ia = *(contacts **)a;
const contacts *ib = *(contacts **)b;
return strcmp(ia->zipCode, ib->zipCode);
}
The output is printing the addresses (I have 50 in an input file) and then some random characters, like a huge block of them, then the sorted list after that which is messed up and not sorted right.
Please any help would be appreciated. I need to learn what's wrong here and why.
Thanx.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
第一条规则:始终检查输入函数 - 在本例中为
fgets()
。如果不检查,您就不知道一切是否正常工作。第二:一般情况下,优先使用
enum
而不是#define
。通过对早期 EOF 的检查,您的代码可以干净地对我的示例数据(6 行)进行排序。它还可以干净地编译 - 这是非常不寻常的(这是一种恭维;我使用严格的警告,甚至我的代码很少第一次就可以干净地编译)。我修改后的代码版本与您的非常相似:
我使用的数据是 4 行集的简单重复,如下所示:
请注意,我在输入中执行的“错误检查”是“有效”的最低限度。如果输入中的行过长,则一个字段将不包含换行符,下一个字段将包含输入行的下一部分(可能是所有其余部分,也可能不是 - 这取决于该行的过长程度)。
First rule: always check input functions - in this case,
fgets()
. You don't know whether everything is working correctly or not if you do not check.Second: use
enum
in preference to#define
in general.With the check for early EOF in place, your code sorted my sample data (6 rows) cleanly. It also compiled cleanly - which is very unusual (that's a compliment; I use stringent warnings and even my code seldom compiles cleanly the first time). My amended version of your code is very similar to yours:
The data I used was trivial repetitions of sets of 4 lines like this:
Note that the 'error checking' I do in the input is the bare minimum that 'works'. If you get an over-long line in the input, one field will not contain a newline, and the next will contain the next section of the input line (possibly all the rest, possibly not - it depends on how badly overlong the line is).
如果您的地址最后打印出垃圾,那么几乎可以肯定是因为您没有为它们分配足够的空间。对于地址来说,二十个字符有点少。
可能发生的情况是,您的地址如下:
并且,当您执行
fgets (street,20,stdin);
时,只会读取14237 Verylongstree
(19 个字符,为空终止符留出空间)。而且,关键在于:文件指针仍然指向
tname Avenue
位,这样,当您尝试读取cityState
时,您就会得到它。而且,当您尝试读取zipCode
时,您将得到cityState
行,从而有效地填充您的排序。If your addresses are printing out rubbish at the end, then it's almost certainly because you haven't allocated enough space for them. Twenty characters is a little on the low side for addresses.
What's probably happening is that you have an address like:
and, when you do
fgets (street,20,stdin);
, only14237 Verylongstree
will be read (19 characters, leaving space for the null terminator).And, here's the crux: the file pointer will still be pointing at the
tname Avenue
bit so that, when you try to read thecityState
, you'll get that. And, when you try to read thezipCode
, you'll get thecityState
line, effectively stuffing up your sorting.我相信你有足够的空间。由于您使用的是 fgets 且大小为 MAX,因此应剪切字符串以适合并在末尾有一个终止 NUL。
有两件事可能会搞砸:
calloc
,它会为您清零内存。尽管更好的想法是使用实际读取的项目数的计数器,而不是假设会有 ELEMENTS 项目。I believe that you have enough space. Because you are using fgets and your size of MAX, the strings should be cut to fit and have a terminating NUL at the end.
Two things that might be messing it up:
calloc
instead, it would zero the memory for you. Although the better idea would be to use a counter of how many items were actually read, instead of assuming there will be ELEMENTS items.