我对C非常陌生,我正在尝试将qsort()与char指针数组一起使用。它没有按我的期望按字母顺序对数组排序,并且删除了第一个元素。我曾尝试调整所有参数,包括比较功能,但无法弄清楚出了什么问题。
输入单词:foo输入单词:bar输入字词:baz输入单词:quux
期望:酒吧巴兹富队列
结果:
酒吧巴兹队列
我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_WORDS 10
#define MAX_LENGTH 20
int read_line(char str[], int n);
int compare(const void *a, const void *b);
int main(void) {
char *words[MAX_WORDS], word[MAX_LENGTH + 1];
int i;
for(i = 0; i < MAX_WORDS; i++) {
printf("Enter word: ");
read_line(word, MAX_LENGTH);
words[i] = malloc(strlen(word) + 1);
if(!words[i]) {
printf("Allocation of memory failed...\n");
exit(EXIT_FAILURE);
}
strcpy(words[i], word);
if(!strlen(words[i]))
break;
}
qsort(&words[0], i, sizeof(char *), compare);
for(int j = 0; j < i; j++) {
printf("%s\n", words[j]);
}
return 0;
}
int read_line(char str[], int n) {
int ch, i;
while((ch = getchar()) != '\n') {
if(i < n)
str[i++] = ch;
}
str[i] = '\0';
return i;
}
int compare(const void *a, const void *b) {
return strcmp((char *) a, (char *) b);
}
问题在于,您只是将第一个字符串传递给qsort,而不是数组的地址。您需要
qsort(words, i, sizeof(char *), compare);
一旦解决此问题,您就会发现您的比较例程不正确,因为它是用word数组的元素而不是其中的值调用的。所以你需要
int compare(const void *a, const void *b) {
return strcmp(*(char **) a, *(char **) b);
}
实际上是从数组中获取char *并比较字符串。
三个错误。
qsort
需要一个指向第一个元素的指针。
qsort(words[0], i, sizeof(char *), compare);
应该是
qsort(&( words[0] ), i, sizeof(char *), compare);
或只是
qsort(words i, sizeof(char *), compare);
后一种版本有效,因为期望指针使用的数组会衰减为指向其第一个元素的指针。
compare
函数获取指向元素的指针。在这种情况下,元素本身就是指针,因此compare接收指向指针的指针。比较功能应为:
static int compare(const void *a, const void *b) {
return strcmp(*(char * const *)a, *(char * const *)b);
}
您的最后一个循环的传递次数太多。
for(int j = 0; j <= i; j++)
应该是
for(int j = 0; j < i; j++)
(除非您真的想在words[i]
中打印长度为0的字符串)。