2

C++: I'm trying to sort some students that are stored in a class by average media.

Only qsort, don't advice me of std::sort, thank you!

Qsort compare function:

int cmp(Student *a, Student *b) {
    return (int)(((Student *)b)->get_media() - ((Student *)a)->get_media());
}

qsort call:

qsort(&tab, (size_t)n, sizeof(tab), (int(*)(const void*, const void*))cmp);

There's no compiler error, but it won't sort.

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

class Student {
private:
    char name[20];
    char surname[20];
    int *marks;
    int group;
    float avg_mark;
public:
    Student()
    {
        char na[20], sur[20];
        int group;
        cout << "\nEnter name: ";
        cin >> na;
        cout << "\nEnter surname: ";
        cin >> sur;
        cout << "\nEnter group: ";
        cin >> group;
        init(na, sur, group);
    }
    ~Student()
    {
        cout << "\ndestructor";
        delete []marks;
    }
    void init(char *n, char *p, int gr)
    {
        strcpy(name, n);
        strcpy(surname, p);
        group = gr;
        marks = new int[6];
        for (int i = 0; i < 6; i++)
        {
            cout << "\nEnter mark " << i + 1 << ": ";
            cin >> *(marks + i);
        }
        avg_mark = media();
    }
    float media()
    {
        int s = 0;
        for (int i = 0; i < 6; i++)
            s += marks[i];
        return ((float)s / 6);
    }
    void set_name(char *n)
    {
        strcpy(name, n);
    }
    char* get_name()
    {
        return name;
    }
    void set_surname(char *p)
    {
        strcpy(name, p);
    }
    char* get_surname()
    {
        return surname;
    }
    int get_group()
    {
        return group;
    }
    float get_media()
    {
        return avg_mark;
    }
};

int cmp(Student *a, Student *b);

int comparator(void *a, void *b) {
    return (int)(((Student *)b)->get_media() - ((Student *)a)->get_media());
}



void main(void)
{
    int n;
    cout << "\nEnter n: ";
    cin >> n;
    Student *tab = new Student[n];
    for (int i = 0; i < n; i++)
        cout << i + 1 << ". " << tab[i].get_name() << " " << tab[i].get_surname() << " Group:" << tab[i].get_group() << " Average mark: " << tab[i].get_media() << endl;
    //qsort(&tab[0], (size_t)n, sizeof(tab), (int*)cmp);
    cout << endl;
    qsort(&tab, (size_t)n, sizeof(tab), (int(*)(const void*, const void*))cmp);
    for (int i = 0; i < n; i++)
        cout << i + 1 << ". " << tab[i].get_name() << " " << tab[i].get_surname() << " Group:" << tab[i].get_group() << " Average mark: " << tab[i].get_media() << endl;
    cin.ignore();
    cin.get();
}

int cmp(Student *a, Student *b) {
    return (int)(((Student *)b)->get_media() - ((Student *)a)->get_media());
}
3
  • 3
    a and b are already Student*s and you're casting them to Student*s. However, when you have to cast a function pointer type, that's a big red flag. You should make a function that matches qsort, not give it something else and pretend it's what it wants. Commented Apr 8, 2017 at 21:19
  • 3
    Do note using qsort on a type that is not trivially copyable is undefined behavior. I know you say you do not want to use std::sort but you really should. Also you do not have a copy constructor defined so you are going to leak memory and/or get doubles deletes which is also undefined behavior. All in all, if you are going to use C++ you really should use C++ and not mix C and C++ together. All you problems can be solved using std::vector, std:string, and std::sort. Commented Apr 8, 2017 at 21:23
  • without that cast it gives error while executing the code. you recommend a method function inside class which returns which one is greater? function's result should be returned by cmp function or directly used in qsort call? Commented Apr 8, 2017 at 21:23

1 Answer 1

1
qsort(&tab, (size_t)n, sizeof(tab), (int(*)(const void*, const void*))cmp);

&tab is the address of the pointer tab. You want to pass the address of the first element of your array. That's &tab[0] or simply tab.

Also, you need to pass the size of a Student object, not the size of a pointer. So change sizeof(tab) to sizeof(Student) or sizeof(*tab). So the call should look like this:

qsort(tab, (size_t)n, sizeof(*tab), (int(*)(const void*, const void*))cmp);
Sign up to request clarification or add additional context in comments.

2 Comments

still not working :( but something happens to the first Student name, first 3 letters of it's name are missing or sometimes is duplicated.
@AndreiD: There was one more problem, I've edited my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.