2017-04-08 4 views
1

C++: Ich versuche, einige Schüler, die in einer Klasse von durchschnittlichen Medien gespeichert sind, zu sortieren.C++ Sortieren Klassenarray mit qsort

Nur qsort, rate mir nicht von std :: sort, danke!

qsort Funktion vergleichen:

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

qsort Aufruf:

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

Es gibt keine Compiler-Fehler, aber es wird nicht sortiert werden.

#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

'a' und' b' sind schon 'Student *' s und du wirst sie zu 'Student *' s. Wenn Sie jedoch einen Funktionszeigertyp umwandeln müssen, ist das eine große rote Markierung. Sie sollten eine Funktion erstellen, die 'qsort' entspricht, nicht etwas anderes geben und so tun, als wäre es das, was es will. – chris

+3

Beachten Sie, dass 'qsort' bei einem Typ, der nicht einfach kopierbar ist, ein nicht definiertes Verhalten ist. Ich weiß, du sagst, du willst nicht 'std :: sort' verwenden, aber du solltest es wirklich tun. Außerdem haben Sie keinen Kopierkonstruktor definiert, so dass Sie Speicher verlieren und/oder doppeltes Löschen erhalten, was ebenfalls ein undefiniertes Verhalten ist. Alles in allem, wenn Sie C++ verwenden, sollten Sie wirklich C++ verwenden und nicht C und C++ zusammen mischen. Alle Probleme können mit 'std :: vector',' std: string' und 'std :: sort' gelöst werden. – NathanOliver

+0

ohne diese Umwandlung gibt es Fehler beim Ausführen des Codes. Sie empfehlen eine Methodenfunktion innerhalb der Klasse, die zurückgibt, welche größer ist? Das Ergebnis der Funktion sollte von der Funktion cmp zurückgegeben oder direkt in qsort call verwendet werden? – AndreiD

Antwort

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

&tab ist die Adresse des Zeigers tab. Sie möchten die Adresse des ersten Elements Ihres Arrays übergeben. Das ist &tab[0] oder einfach tab.

Außerdem müssen Sie die Größe eines Student Objekts übergeben, nicht die Größe eines Zeigers. Ändern Sie also sizeof(tab) zu sizeof(Student) oder sizeof(*tab). So sollte der Anruf so aussehen:

+0

immer noch nicht funktioniert :(aber etwas passiert mit dem ersten Student Name, erste 3 Buchstaben seines Namens fehlen oder manchmal ist doppelt. – AndreiD

+0

@AndreiD: Es gab noch ein Problem, ich habe meine Antwort bearbeitet. –

+0

Du bist erstaunlich ! Problem gelöst :) – AndreiD