Arrays 如何使用qsort对结构指针数组进行排序

Arrays 如何使用qsort对结构指针数组进行排序,arrays,c,pointers,struct,qsort,Arrays,C,Pointers,Struct,Qsort,这是我的书结构,这是我的代码: typedef struct book { char title[100]; char author[20]; int price; } BOOK; #define MAX_SIZE 10 int comparePrice(const void *bookA, const void *bookB); int count = 0; int main() { BOOK *books[MAX_SIZE]; // here

这是我的
结构,这是我的代码:

typedef struct book {
   char title[100];
   char author[20];
   int price;
} BOOK;

#define MAX_SIZE 10

int comparePrice(const void *bookA, const void *bookB);

int count = 0;

int main() {    
    BOOK *books[MAX_SIZE];    // here is  array of struct pointers
    while (1) {   
        char title[100] = "";
        char author[20] = "";
        int price = -1;
        //////////// printf select menu ////////////
        int selector = -1;
        scanf("%d", &selector);
        switch (selector) {
          case 1:
            while (getchar() != '\n');
            printf("--------input book data--------\n");
            printf("title :");
            gets(title);
            printf("author :");
            gets(author);

            printf("price :");
            scanf("%d", &price);

            books[count] = (BOOK *) malloc(sizeof(BOOK));
            memset(books[count], 0, sizeof(BOOK));
            strcpy(books[count]->title, title);
            strcpy(books[count]->author, author);
            books[count]->price = price;
            count++;
            break;
          case 4:
            printf("--------sorting price--------\n");
            qsort(books, count, sizeof(BOOK), comparePrice);
            for (int i = 0; i < count; ++i) {
                printf("%d. title: %s author: %s price: %d\n", i + 1, books[i]->title, books[i]->author, books[i]->price);
            }
            break;
          default:
            for (int i = 0; i < MAX_SIZE; ++i) {
                free(books[i]);
                books[i] = NULL;
            }
            return 0;
        }
    }
}

int comparePrice(const void *bookA, const void *bookB) {
    const BOOK *a = (const BOOK *)bookA;
    const BOOK *b = (const BOOK *)bookB;
    return b->price - a->price;
}
typedef结构书{
字符标题[100];
char作者[20];
国际价格;
}书;
#定义最大尺寸10
int比较价格(常数无效*账簿A,常数无效*账簿B);
整数计数=0;
int main(){
BOOK*books[MAX_SIZE];//这里是结构指针数组
而第(1)款{
字符标题[100]=“”;
字符作者[20]=“”;
整数价格=-1;
////////////打印选择菜单////////////
int选择器=-1;
scanf(“%d”,选择器(&S);
开关(选择器){
案例1:
而(getchar()!='\n');
printf(“----输入图书数据-----\n”);
printf(“标题:”);
获取(标题);
printf(“作者:”);
获取(作者);
printf(“价格:”);
scanf(“%d”和“价格”);
图书[数量]=(图书*)malloc(图书大小);
memset(books[count],0,sizeof(BOOK));
strcpy(书籍[计数]->标题,标题);
strcpy(书籍[计数]->作者,作者);
书籍[计数]->价格=价格;
计数++;
打破
案例4:
printf(“----排序价格----\n”);
qsort(书籍、计数、大小(书籍)、比较价格);
对于(int i=0;i标题,图书[i]->作者,图书[i]->价格);
}
打破
违约:
对于(int i=0;iprice-a->price;
}
但是
qsort
不起作用 选择4号菜单,此程序停止。 我试着调试,发现a和b有未知的值。 在printf语句中出现
EXC\u BAD\u ACCESS
错误以打印排序结果。
排序需要做什么。

比较函数不正确:它将指针获取到数组中,因此指向结构指针的指针。此外,如果减法溢出,则通过减法比较整数不起作用,这在比较非常大的相反符号值时是可能的

以下是修改后的版本:

int comparePrice(const void *aa, const void *bb) {
    const BOOK *a = *(const BOOK * const *)aa;
    const BOOK *b = *(const BOOK * const *)bb;
    /* sort in decreasing order of price */
    return (b->price > a->price) - (b->price < a->price);
}
代码中还有其他问题:

  • 数组
    books
    未初始化,因此您应该只
    释放已分配的指针:将最后一个循环更改为

      while (count > 0) {
          free(books[--count]);
      }
    
  • 不要使用
    get()

  • 小心潜在的无限循环:
    while(getchar()!='\n')
    始终测试
    EOF

      int c;
      while ((c = getchar()) != EOF && c != '\n')
          continue;
    

qsort将数组中元素的指针传递给compar函数(在您的例子中,它本身就是指针)。所以你想要:

int comparePrice(const void *bookA, const void *bookB) {
    const BOOK *a = *(const BOOK **)bookA;
    const BOOK *b = *(const BOOK **)bookB;
    return b->price - a->price;
}

应该初始化数组
book

BOOK *books[MAX_SIZE] = { NULL };
否则这个循环

for (int i = 0; i < MAX_SIZE; ++i) {
    free(books[i]);
    books[i] = NULL;
}
另一方面,函数
comparePrice
应按以下方式定义

int comparePrice( const void *bookA, const void *bookB ) 
{
    const BOOK *a = *( const BOOK * const * ) bookA;
    const BOOK *b = *( const BOOK * const * ) bookB;
    
    return ( a->price < b->price ) - ( b->price < a->price );
}

PSST,如果您使用
calloc
,您不需要
memset
自己将所有内容设置为0。如果您忘记释放
,则会导致内存泄漏。和
strcpy也很危险。编辑得不错,但不能保证
books
数组具有
MAX\u SIZE
元素。因此,您可能正在尝试释放未初始化的指针。使用
count
@YIGeon你想按降序排序吗?@VladfromMoscow是的!
qsort( books, count, sizeof( BOOK * ), comparePrice );
int comparePrice( const void *bookA, const void *bookB ) 
{
    const BOOK *a = *( const BOOK * const * ) bookA;
    const BOOK *b = *( const BOOK * const * ) bookB;
    
    return ( a->price < b->price ) - ( b->price < a->price );
}
#include <stdio.h>
#include <stdlib.h>

typedef struct book
{
    int price;
} BOOK;

int comparePrice( const void *bookA, const void *bookB ) 
{
    const BOOK *a = *( const BOOK * const * ) bookA;
    const BOOK *b = *( const BOOK * const * ) bookB;
    
    return ( a->price < b->price ) - ( b->price < a->price );
}

int main(void) 
{
    BOOK b1 = { 10 }, b2 = { 20 };
    BOOK *a[] = { &b1, &b2 };
    const size_t count = sizeof( a ) / sizeof( *a );
    
    for ( size_t i = 0; i < count; i++ )
    {
        printf( "%d ", a[i]->price );
    }
    
    putchar( '\n' );

    qsort( a, count, sizeof( BOOK * ), comparePrice );
    
    for ( size_t i = 0; i < count; i++ )
    {
        printf( "%d ", a[i]->price );
    }
    
    putchar( '\n' );
    
    return 0;
}
10 20 
20 10