【问题标题】:Need help sorting an array of structures in C using qsort需要帮助使用 qsort 对 C 中的结构数组进行排序
【发布时间】:2016-11-29 22:06:31
【问题描述】:

我有这个结构。

struct Transport
{
   int id;
   float Price;
};

在这里,我将数据读入结构数组。

void read (struct Transport **Car, int *m)
{
    int i;
    printf("Insert total number of cars: ");
    scanf("%d",m);
    *Car=(struct Transport*) malloc ((*m)*3*sizeof(struct Transport));               

    for(i=1; i<=*m; i++)
    {
       (*Car)[i].id=i;
       printf("Price: ");
       scanf("%f",&(*Car)[i].Price);
       printf("\n");
    }
}

这里是显示功能。

void display(struct Transport *Car,int m)
{
    int i;
    for(i=1; i<=m; i++)
    {
        printf("Entry #%d: \n",i);
        printf("Price: %2.2f\n",(Car+i)->Price);
        printf("\n");
    }
}

现在问题来了。我必须按价格字段对数据进行排序。到目前为止,我已经尝试过了,但它什么也没做。

int struct_cmp_by_price(const void *a, const void *b)
{
    struct Transport *ia = (struct Transport *)a;
    struct Transport *ib = (struct Transport *)b;
    return (int)(100.f*ia->Price - 100.f*ib->Price);
}

这是主要的样子。

int main()
{
    int m;
    struct Transport *Car;
    read(&Car,&m);
    qsort(Car, m, sizeof(struct Transport), struct_cmp_by_price);
    display(Car,m);
    return 0;
}

谁能帮帮我?

【问题讨论】:

  • qsort(Car, --> qsort(Car+1,for(i=1; i&lt;=*m --> for(i=0; i&lt;*m
  • 数组索引在 C 中从 0 开始
  • 对 Car+1 排序并不能修复数组末尾的添加。更改 for 循环。
  • 成功了,非常感谢!
  • @MichaelDorgan 根据需要三倍保护。 malloc ((*m)*3*sizeof(struct Transport));

标签: c arrays sorting struct qsort


【解决方案1】:

您的代码存在多个问题:

  • 你在read()中分配了太多的内存,你不需要在C中强制转换malloc()的返回值,但是你应该检查分配失败。你应该改用:

    *Car = calloc(*m, sizeof(struct Transport));
    if (*Car == NULL) {
        fprintf(stderr, "cannot allocate memory for %d structures\n", *m);
        exit(1);
    }
    
  • 您不应使用read 作为函数名,因为它是系统调用的名称,可能与该函数的标准库使用冲突。使用readTransport

  • 索引是基于 C 的 0。而不是 for(i=1; i&lt;=*m; i++),请使用:

    for (i = 0; i < *m; i++)
    
  • 比较函数不能使用减法技巧。事实上,减法技巧只能用于小于int 的整数类型。改用这个:

    int struct_cmp_by_price(const void *a, const void *b) {
        const struct Transport *ia = a;
        const struct Transport *ib = b;
        return (ia->Price > ib->Price) - (ia->Price < ib->Price);
    }
    
  • 您应该测试scanf() 的返回值以检测无效输入。 Price 成员在转换失败的情况下未初始化,这会导致未定义的行为,除非您使用 calloc(),但结果仍然没有意义。

【讨论】:

    【解决方案2】:

    您也可以尝试使用两个单独的结构,以使指针操作更易于处理。

    这样的事情给出了正确的想法:

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct {
        int id;
        float price;
    } transport_t;
    
    typedef struct {
        transport_t *Cars;
        int numcars;
    } Cars_t;
    
    Cars_t *initialize_struct(void);
    void read(Cars_t *Car);
    void display(Cars_t *Car);
    int price_cmp(const void *x, const void *y);
    
    int 
    main(void) {
        Cars_t *Car;
    
        Car = initialize_struct();
    
        read(Car);
    
        printf("Before:\n");
        display(Car);
    
        qsort(Car->Cars, Car->numcars, sizeof(transport_t), price_cmp);
    
        printf("\nAfter:\n");
        display(Car);
    
        free(Car->Cars);
        free(Car);
    
        return 0;
    }
    
    void
    read(Cars_t *Car) {
        int i, count = 0;
    
        printf("Insert total number of cars: ");
        if (scanf("%d", &(Car->numcars)) != 1) {
            printf("Invalid entry\n");
            exit(EXIT_FAILURE);
        }
    
        Car->Cars = calloc(Car->numcars, sizeof(transport_t));
        if (Car->Cars == NULL) {
            fprintf(stderr, "Issue allocating memory for %d members", Car->numcars);
            exit(EXIT_FAILURE);
        }
    
        for (i = 1; i <= Car->numcars; i++) {
            Car->Cars[count].id = i;
            printf("Car id %d\n", Car->Cars[count].id);
    
            printf("Price: ");
            scanf("%f", &(Car->Cars[count].price));
    
            count++;
    
            printf("\n");
        }
    }
    
    void
    display(Cars_t *Car) {
        int i;
    
        for (i = 0; i < Car->numcars; i++) {
            printf("Car id: %d, Car price: %2.2f\n", 
                    Car->Cars[i].id, Car->Cars[i].price);
        }
    }
    
    Cars_t
    *initialize_struct(void) {
        Cars_t *Car;
    
        Car = malloc(sizeof(*Car));
        if (Car == NULL) {
            fprintf(stderr, "%s", "Issue allocating memory for structure");
            exit(EXIT_FAILURE);
        }
    
        Car->Cars = NULL;
        Car->numcars = 0;
    
        return Car;
    } 
    
    int
    price_cmp(const void *x, const void *y) {
        const transport_t *car1 = x;
        const transport_t *car2 = y;
    
        if (car1->price > car2->price) {
            return +1;
        } else if (car1->price < car2->price) {
            return -1;
        }
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-31
      • 2021-07-16
      • 1970-01-01
      • 1970-01-01
      • 2014-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多