需要帮助使用qsort对C中的结构数组进行排序 [英] Need help sorting an array of structures in C using qsort

查看:125
本文介绍了需要帮助使用qsort对C中的结构数组进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个结构.

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;
}

有人可以帮助我吗?

解决方案

您的代码中存在多个问题:

  • 您在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.使用

    *Car = calloc(*m, sizeof(struct Transport));
    if (*Car == NULL) {
        fprintf(stderr, "cannot allocate memory for %d structures\n", *m);
        exit(1);
    }
    

    代替for(i=1; i<=*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()的返回值以检测无效的输入.除非您使用calloc(),否则在转换失败的情况下Price成员将保持未初始化状态,这将导致不确定的行为,但是结果仍然没有意义.

I have this struct.

struct Transport
{
   int id;
   float Price;
};

Here I read the data into and array of structs.

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");
    }
}

And here is the display function.

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");
    }
}

Now here is the problem.I must sort the data by the Price field. So far I've tried this, but it does nothing.

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);
}

Here is how the main looks like.

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;
}

Can anyone help me?

解决方案

There are multiple problems in your code:

  • You allocate too much memory in read(), and you do not need to cast the return value of malloc() in C, but you should check for allocation failure. you should instead use:

    *Car = calloc(*m, sizeof(struct Transport));
    if (*Car == NULL) {
        fprintf(stderr, "cannot allocate memory for %d structures\n", *m);
        exit(1);
    }
    

  • You should not use read as a function name because it is the name of a system call and may conflict with the standard library use of that function. Use readTransport.

  • indexes are 0 based in C. Instead of for(i=1; i<=*m; i++), use:

    for (i = 0; i < *m; i++)
    

  • The comparison function cannot use the subtraction trick. As a matter of fact, the subtraction trick can only be used for integer types smaller than int. Use this instead:

    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);
    }
    

  • You should test the return value of scanf() to detect invalid input. The Price members are left uninitialized in case of conversion failure, which leads to undefined behavior, unless you use calloc(), but the result is still meaningless.

这篇关于需要帮助使用qsort对C中的结构数组进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆