鱼C论坛

 找回密码
 立即注册
查看: 387|回复: 2

[已解决]库函数qsort使用出错

[复制链接]
发表于 2024-2-19 13:10:59 | 显示全部楼层 |阅读模式
21鱼币
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. #define MAX_LEN 20

  5. struct word {
  6.         char *word;
  7.         struct word *next;
  8. };

  9. void *malloc_word(void);
  10. char *read_word(void);
  11. int compare_word(const void *p, const void *q);

  12. int main(void)
  13. {
  14.         struct word *first = NULL;
  15.         for (int i = 0; first == NULL && i < 3; i++)
  16.                 first = malloc_word();

  17.         int num_words = 0;
  18.         char *word;
  19.         struct word *p, *last;
  20.         p = first;
  21.         do {
  22.                 printf("Enter a word: ");
  23.                 word = read_word();
  24.                 p->word = malloc(MAX_LEN);
  25.                 if (p->word == NULL)
  26.                         exit -1;
  27.                 strcpy(p->word, word);
  28.                 num_words++;
  29.                 p->next = malloc_word();
  30.                 if (p->next != NULL) {
  31.                         last = p;
  32.                         p = p->next;
  33.                 }
  34.                 else
  35.                         return 1;
  36.         }while (strcmp(word, "\n"));
  37.         free(p);
  38.         p = last;
  39.         p->next = NULL;
  40.         num_words--;

  41.         qsort(first, num_words, sizeof(struct word), compare_word);

  42.         printf("In sorted order: ");
  43.         p = first;
  44.         for (int i = 0; i < num_words; i++)
  45.         {
  46.                 printf("%s ", p->word);
  47.                 p = p->next;
  48.         }
  49.         putchar('\n');

  50.         return 0;
  51. }

  52. void *malloc_word(void)
  53. {
  54.         struct word *p;
  55.         p = malloc(sizeof(struct word));
  56.         if (p != NULL)
  57.                 return p;
  58.         return NULL;
  59. }

  60. char *read_word(void)
  61. {
  62.         char *word;
  63.         word = malloc(MAX_LEN);
  64.         if (word == NULL)
  65.                 exit -1;
  66.         int ch;
  67.         int i;
  68.         for (i = 0, ch = getchar(); ch != '\n'; ch = getchar(), i++)
  69.                 word[i] = ch;

  70.         if (i == 0)
  71.                 word[i] = ch;

  72.         return word;
  73. }

  74. int compare_word(const void *p, const void *q)
  75. {
  76. //      return strcmp(((struct word *) p)->word, ((struct word *) q)->word);
  77.         return ((struct word *) p)->word - ((struct word *) q)->word;
  78. }
复制代码


只要加上qsort那一行,在那一行就会出错崩溃
最佳答案
2024-2-19 13:11:00
qsort 函数在C语言中用于对数组进行排序。

它需要以下几个参数:
  • 数组的指针
  • 数组中元素的数量
  • 每个元素的大小的比较函数


在鱼油的代码中, qsort 用于排序的对象不是一个数组,而是一个链表。

这是造成崩溃的原因。

链表和数组在内存中的组织方式完全不同。

数组是连续内存块,而链表由一系列使用指针链接的节点组成,这些节点可以分散在内存的不同位置。

qsort 期望一个连续的内存块来访问和交换元素,这与链表的结构不兼容。

此外, compare_word 函数中的比较逻辑也是不正确的。

strcmp 函数是正确比较两个字符串的方法,您注释掉的那行应该是正确的。

当前未注释的行试图直接比较指针值,而不是它们所指向的字符串内容。

要修复这个问题,您需要实现一个专门针对链表排序的算法,例如归并排序。

如果想要使用 qsort ,则必须首先将链表的内容复制到一个数组中,对数组进行排序,然后再将排序后的内容回写到链表中。



如果决定改用数组并使用 qsort ,您的 compare_word 函数应该如下所示:

  1. int compare_word(const void *p, const void *q)
  2. {
  3.     const struct word *wp = p;
  4.     const struct word *wq = q;
  5.     return strcmp(wp->word, wq->word);
  6. }
复制代码

如果希望继续使用链表,那么需要使用不同的方法来排序,而不是 qsort 。

最佳答案

查看完整内容

qsort 函数在C语言中用于对数组进行排序。 它需要以下几个参数: [*]数组的指针 [*]数组中元素的数量 [*]每个元素的大小的比较函数 在鱼油的代码中, qsort 用于排序的对象不是一个数组,而是一个链表。 这是造成崩溃的原因。 链表和数组在内存中的组织方式完全不同。 数组是连续内存块,而链表由一系列使用指针链接的节点组成,这些节点可以分散在内存的不同位置。 qsort 期望一个连续的内存块来访问 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-2-19 13:11:00 | 显示全部楼层    本楼为最佳答案   
qsort 函数在C语言中用于对数组进行排序。

它需要以下几个参数:
  • 数组的指针
  • 数组中元素的数量
  • 每个元素的大小的比较函数


在鱼油的代码中, qsort 用于排序的对象不是一个数组,而是一个链表。

这是造成崩溃的原因。

链表和数组在内存中的组织方式完全不同。

数组是连续内存块,而链表由一系列使用指针链接的节点组成,这些节点可以分散在内存的不同位置。

qsort 期望一个连续的内存块来访问和交换元素,这与链表的结构不兼容。

此外, compare_word 函数中的比较逻辑也是不正确的。

strcmp 函数是正确比较两个字符串的方法,您注释掉的那行应该是正确的。

当前未注释的行试图直接比较指针值,而不是它们所指向的字符串内容。

要修复这个问题,您需要实现一个专门针对链表排序的算法,例如归并排序。

如果想要使用 qsort ,则必须首先将链表的内容复制到一个数组中,对数组进行排序,然后再将排序后的内容回写到链表中。



如果决定改用数组并使用 qsort ,您的 compare_word 函数应该如下所示:

  1. int compare_word(const void *p, const void *q)
  2. {
  3.     const struct word *wp = p;
  4.     const struct word *wq = q;
  5.     return strcmp(wp->word, wq->word);
  6. }
复制代码

如果希望继续使用链表,那么需要使用不同的方法来排序,而不是 qsort 。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-2-19 13:11:08 | 显示全部楼层
这是因为你在比较函数`compare_word`中使用了错误的指针减法操作`((struct word *) p)->word - ((struct word *) q)->word`。指针减法操作只适用于两个指针指向同一个数组或同一个数据结构的不同成员时才能得到正确的结果,而不是用于比较字符串的字典顺序。

正确的做法是使用`strcmp`函数来比较字符串的字典顺序,就像你注释掉的那一行代码一样:

  1. return strcmp(((struct word *) p)->word, ((struct word *) q)->word);
复制代码


这样就可以正常地使用`qsort`函数进行排序了。希望能帮到你!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 22:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表