2016-11-29 155 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; 
}