1

I have to sort the cricketers in ascending order of the average run scored by them using qsort() function and then print all the details according to it. I am not able to figure out that how can I sort according to the average run scored and then print the list according to it.

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

int compare(const void*a, const void*b)
{
    return (*(int*)a - *(int*)b);
}

void main()
{
    int i;
    struct cricket
    {
        char name[20];
        int age;
        int no_test;
        int avrun;
    }
    players[20] = {
        "Virat Kohli", 25, 29, 94,
        "Rohit Sharma", 26, 19, 86,
        "Mahendra Singh Dhoni", 32, 40, 69,
        "Gautum Gambhir", 29, 28, 90,
        "Hardik Pandya", 27, 18, 59,
        "Chris Gayle", 38, 50, 48,
        "James Watson", 40, 54, 68,
        "Brett Lee", 38, 53, 83,
        "Suresh Raina", 32, 29, 59,
        "Sachin Tendulkar", 40, 60, 95,
        "Virendra Sehwag", 45, 55, 83
    };
    qsort(players,11,sizeof(cricket),compare);
    for(i = 0; i < 11; i++)
    {
        printf("%s ", players[i].name);
        printf("%d ", players[i].age);
        printf("%d ", players[i].no_test);
        printf("%d \n", players[i].avrun);
    }
    getch();
}
Cid
  • 14,968
  • 4
  • 30
  • 45
sayantan
  • 21
  • 6
  • 3
    the `compare` function will be called with two pointers to `cricket` instances. You'll have to make the definition of `cricket` visible to the `compare` function, and then cast the pointers and compare based on the data member of your choice. – Sander De Dycker Jul 02 '18 at 08:25
  • 1
    ... and please format your code the way they did it in your C text book – Jabberwocky Jul 02 '18 at 08:29
  • 1
    The most minimal change to get the required result would be to move the member `avrun` to the beginning of `strcut cricket`. – alk Jul 02 '18 at 08:41
  • 1
    `void main() {…}` --> `int main(void){…}` and why are you defining `struct cricket` in `main`? – Bob__ Jul 02 '18 at 08:42
  • 1
    @alk : while technically correct, I wouldn't recommend that since the resulting code will be quite brittle (at the very least, it'll have to be clearly documented that the first member should not be changed) – Sander De Dycker Jul 02 '18 at 08:53

2 Answers2

1

Change void main() to int main(void). What should main() return in C and C++?

You might not want to use conio.h.

The definition of struct cricket should be visible to the compare(), so move it before that function (just after the header files).

Then you need a semicolon at the end of the struct's definition.

Now you need to declare the type of your array, like this: struct cricket players[20].

Then, you should receive this warning:

warning: missing braces around initializer [-Wmissing-braces]

about the way you initialize your players. You need to do it like this:

struct cricket players[20] = {
       {"Virat Kohli", 25, 29, 94},
       {"Rohit Sharma", 26, 19, 86},
       ...
};

Then, you have to fix this error:

error: 'cricket' undeclared (first use in this function) qsort(players,11,sizeof(cricket),compare);

just by replacing cricket with struct cricket.

Putting everything together, you have:

#include <stdio.h>
#include <stdlib.h>

struct cricket {
    char name[20];
    int age;
    int no_test;
    int avrun;
};

int compare(const void*a, const void*b) {
    return (*(int*)a - *(int*)b);
}

int main(void) {
    int i;
    // I changed the size of the array too, to 11.
    struct cricket players[11] = {
        {"Virat Kohli", 25, 29, 94},
        {"Rohit Sharma", 26, 19, 86},
        {"Mahendra Singh Dhoni", 32, 40, 69},
        {"Gautum Gambhir", 29, 28, 90},
        {"Hardik Pandya", 27, 18, 59},
        {"Chris Gayle", 38, 50, 48},
        {"James Watson", 40, 54, 68},
        {"Brett Lee", 38, 53, 83},
        {"Suresh Raina", 32, 29, 59},
        {"Sachin Tendulkar", 40, 60, 95},
        {"Virendra Sehwag", 45, 55, 83}
    };
    qsort(players,11,sizeof(struct cricket),compare);
    for(i = 0; i < 11; i++) {
        printf("%s ", players[i].name);
        printf("%d ", players[i].age);
        printf("%d ", players[i].no_test);
        printf("%d \n", players[i].avrun);
    }
    return 0;
}

which will run and produce an output with no meaning. In your compare function, you should think on which field you want your array to be sorted.

Understand what was mentioned in this question, and then move on and modify your compare function.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
1

Your comparison function makes no sense.

For it to work, the data type being sorted must be known, so you can't hide the structure declaration from it.

Assuming you move that to the top, you can then re-write the comparison function:

static int compare_crickets(const void *va, const void *vb)
{
  // Convert the generic arguments to actual structure pointers.
  const struct cricket * const ca = va, * const cb = vb;
  // Compare on the 'avrun' member, return -1/0/1 for LT/EQ/GT.
  return ca->avrun < cb->avrun ? -1 : ca->avrun > cb->avrun;
}
unwind
  • 391,730
  • 64
  • 469
  • 606