问题
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?
回答1:
There are multiple problems in your code:
You allocate too much memory in
read(), and you do not need to cast the return value ofmalloc()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
readas a function name because it is the name of a system call and may conflict with the standard library use of that function. UsereadTransport.indexes are
0based in C. Instead offor(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. ThePricemembers are left uninitialized in case of conversion failure, which leads to undefined behavior, unless you usecalloc(), but the result is still meaningless.
回答2:
You can also try using two separate structs, to make pointer operations easier to handle.
Something like this gives the right idea:
#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;
}
来源:https://stackoverflow.com/questions/40876657/need-help-sorting-an-array-of-structures-in-c-using-qsort