Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
qsort()出现问题-排序未正确完成(C)_C_Sorting_Qsort - Fatal编程技术网

qsort()出现问题-排序未正确完成(C)

qsort()出现问题-排序未正确完成(C),c,sorting,qsort,C,Sorting,Qsort,我有一个关于qsort的问题 这有点奇怪,但是我的qsort函数没有给我正确的输出。奇怪的是,我的一些比较函数与我以前的项目相同,但它们根本没有给我正确的输入。我不知道如何测试它 例如: int comp_name_asc(const void *a, const void *b) { const Rec *prec1 = (const Rec *) a; const Rec *prec2 = (const Rec *) b; return strcmp(prec1->name

我有一个关于qsort的问题

这有点奇怪,但是我的qsort函数没有给我正确的输出。奇怪的是,我的一些比较函数与我以前的项目相同,但它们根本没有给我正确的输入。我不知道如何测试它

例如:

int comp_name_asc(const void *a, const void *b)
{
  const Rec *prec1 = (const Rec *) a;
  const Rec *prec2 = (const Rec *) b;
  return strcmp(prec1->name, prec2->name); 
}

int comp_name_desc(const void *a, const void *b)
{
  const Rec *prec1 = (const Rec *) a;
  const Rec *prec2 = (const Rec *) b;
  return strcmp(prec2->name, prec1->name);
}
第二个函数应该是降序的,但是结果是一样的:它总是以升序的。我已检查以确保在正确的时间输入正确的功能。Rec是我创建的结构的typedef,它有一个char*name参数

另外(修改以避免溢出):

我真的不知道如何调试这个。我所知道的是,输入了适当的比较函数,过去使用过一些类似的比较函数

任何想法或我如何调试这将是欢迎的。多谢各位

编辑:

正在添加对qsort的调用:

int index = 0;
Rec **array = (Rec **) malloc(sizeof(Rec *) * capacity);
// Adds element to the array...
qsort(array, index, sizeof(Rec *), comp_name_desc);
(每次向数组中添加元素时,索引都会增加。)

谢谢

编辑:

下面给出了解决方案。谢谢大家!

我必须改变:

const Rec *prec1 = (const Rec *) a;


因为我是如何定义数组的。谢谢

你永远不应该用一个减去另一个来比较数字。这通常会导致有符号类型溢出,而对无符号类型根本不起作用。将数字与三态结果进行比较的通用习惯用法如下

(a > b) - (a < b)
(a>b)-(a

否则,您的比较函数看起来很好,所以问题一定是在调用排序函数的方式上。

听到行为是什么,一种预感可能是名称实际上不是名称,如果
strcmp()
交换了两个参数,并且结果仍在上升。一个建议可能是使用
printf
打印出名称,并且将名称减少到2或3(记录数),以便更容易调试和检查其行为的原因。

您是否有
Rec
数组,或者更确切地说是
Rec
指针数组?我这样问是因为比较函数作为参数指针进入数组,而不是直接指向记录

以下是两种方法的演示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Rec {
  char *name;
} Rec;

/*
 * The pointers a and b point directly into the array,
 * where the Records themselves are.
 */
static int
cmp_Rec_by_name(const void *a, const void *b) {
  const Rec *rec1 = (Rec *)a;
  const Rec *rec2 = (Rec *)b;
  return strcmp(rec1->name, rec2->name);
}

/*
 * The pointers point directly into the array, where
 * not the records but pointers to them are. So they
 * are a pointer to a pointer to a record.
 */
static int
cmp_Rec_ptr_by_name(const void *a, const void *b) {
  const Rec *rec1 = *(Rec **)a;
  const Rec *rec2 = *(Rec **)b;
  return strcmp(rec1->name, rec2->name);
}

static void
sort_Rec(void) {
  Rec record[3];

  record[0].name = strdup("hello");
  record[1].name = strdup("world");
  record[2].name = strdup("how are you");
  qsort(record, 3, sizeof (Rec), cmp_Rec_by_name);

  for (int i = 0; i < 3; i++)
    printf("%s\n", record[i].name);
}

static void
sort_Rec_ptr(void) {
  Rec *(record[3]);

  record[0] = malloc(sizeof (Rec));
  record[1] = malloc(sizeof (Rec));
  record[2] = malloc(sizeof (Rec));
  record[0]->name = strdup("hello");
  record[1]->name = strdup("world");
  record[2]->name = strdup("how are you");
  qsort(record, 3, sizeof (Rec *), cmp_Rec_ptr_by_name);

  for (int i = 0; i < 3; i++)
    printf("%s\n", record[i]->name);
}

int
main() {
  sort_Rec();
  sort_Rec_ptr();
  return 0;
}
#包括
#包括
#包括
类型定义结构记录{
字符*名称;
}Rec;
/*
*指针a和b直接指向数组,
*记录本身所在的位置。
*/
静态整数
cmp按名称记录(常数无效*a,常数无效*b){
常数Rec*rec1=(Rec*)a;
常数Rec*rec2=(Rec*)b;
返回strcmp(rec1->name,rec2->name);
}
/*
*指针直接指向数组,其中
*不是记录,而是指向它们的指针。所以他们
*是指向记录指针的指针。
*/
静态整数
cmp按名称记录ptr(常数无效*a,常数无效*b){
常数Rec*rec1=*(Rec**)a;
常数Rec*rec2=*(Rec**)b;
返回strcmp(rec1->name,rec2->name);
}
静态空隙
分类记录(作废){
Rec记录[3];
记录[0]。名称=strdup(“你好”);
记录[1]。名称=strdup(“世界”);
记录[2]。name=strdup(“你好”);
qsort(记录,3,大小(Rec),cmp_Rec_按名称);
对于(int i=0;i<3;i++)
printf(“%s\n”,记录[i].name);
}
静态空隙
分拣记录(作废){
记录*(记录[3]);
记录[0]=malloc(sizeof(Rec));
记录[1]=malloc(sizeof(Rec));
记录[2]=malloc(sizeof(Rec));
记录[0]->name=strdup(“你好”);
记录[1]->name=strdup(“世界”);
记录[2]->name=strdup(“你好”);
qsort(记录,3,大小(记录*)、cmp(记录)和ptr(按名称);
对于(int i=0;i<3;i++)
printf(“%s\n”,记录[i]->名称);
}
int
main(){
sort_Rec();
sort_Rec_ptr();
返回0;
}

欢迎来到SO+我想问你一个写得很好的问题和格式很好的代码。你能展示一下你调用qsort()的代码吗?在“升序大小”的情况下,记录是否按名称排序?顺便说一句,在比较函数中使用减法不是一个好主意:在整数溢出的情况下,您将得到不一致的比较。从提供的代码中,我想不出任何可能的原因。请提供psmears建议的更多代码。另外,我建议注释掉
comp\u name\u asc
并使用
comp\u name\u desc
运行
qsort
。告诉我们发生了什么,谢谢。为了回复上一条评论,我只是尝试了一下,它是按升序排列的:即:背,球,绿色,图像…谢谢,我没有想到这一点。我会用一些if-else-if-else语句来解决这个问题。一个非常好的答案。。。这也将考虑到实数(浮点/双精度)-减法不起作用…非常感谢,你是对的,它应该是:const Rec*rec1=*(Rec**)a;我的问题已经解决了,非常感谢!使用
const Rec Rec 1=*(Rec*)a
可以复制整个记录,但不需要复制。这就是为什么我在
cmp\u Rec\u ptr\u by\u name
中使用指针。
const Rec *prec1 = *(const Rec **) a;
(a > b) - (a < b)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Rec {
  char *name;
} Rec;

/*
 * The pointers a and b point directly into the array,
 * where the Records themselves are.
 */
static int
cmp_Rec_by_name(const void *a, const void *b) {
  const Rec *rec1 = (Rec *)a;
  const Rec *rec2 = (Rec *)b;
  return strcmp(rec1->name, rec2->name);
}

/*
 * The pointers point directly into the array, where
 * not the records but pointers to them are. So they
 * are a pointer to a pointer to a record.
 */
static int
cmp_Rec_ptr_by_name(const void *a, const void *b) {
  const Rec *rec1 = *(Rec **)a;
  const Rec *rec2 = *(Rec **)b;
  return strcmp(rec1->name, rec2->name);
}

static void
sort_Rec(void) {
  Rec record[3];

  record[0].name = strdup("hello");
  record[1].name = strdup("world");
  record[2].name = strdup("how are you");
  qsort(record, 3, sizeof (Rec), cmp_Rec_by_name);

  for (int i = 0; i < 3; i++)
    printf("%s\n", record[i].name);
}

static void
sort_Rec_ptr(void) {
  Rec *(record[3]);

  record[0] = malloc(sizeof (Rec));
  record[1] = malloc(sizeof (Rec));
  record[2] = malloc(sizeof (Rec));
  record[0]->name = strdup("hello");
  record[1]->name = strdup("world");
  record[2]->name = strdup("how are you");
  qsort(record, 3, sizeof (Rec *), cmp_Rec_ptr_by_name);

  for (int i = 0; i < 3; i++)
    printf("%s\n", record[i]->name);
}

int
main() {
  sort_Rec();
  sort_Rec_ptr();
  return 0;
}