2016-11-29 154 views
1

我有这个结构。需要帮助使用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; 
} 

任何人都可以帮我吗?

+1

'的qsort(汽车,' - >'的qsort(车载+ 1,'或'为(I = 1;我<=*m' -->'为(ⅰ= 0; i <* m' – BLUEPIXY

+1

数组索引从0开始在C中 –

+0

对Car + 1进行排序并不能修复数组添加结束时更改for循环 –

回答

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语言而不是for(i=1; i<=*m; i++),使用0

    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(),但结果仍然没有意义。

0

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

像这样给出正确的想法:

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