2017-03-15 3 views
1

Ich möchte QSort in meinem Programm verwenden, um Elemente im Zeiger auf Zeiger auf struct zu sortieren. Das erste Element ist in Ordnung, aber dann ist es durcheinander. Die Funktion scheint einige Elemente zu lesen, aber in falscher Reihenfolge/Position.QSort gibt falsche (verschlüsselte?) Zahlen in cmp-Funktion zurück

Hier ist mein Code

... 

typedef struct Date { 
    int day; 
    int month; 
    int year; 
} Date; 

... 

// Sorts the date date_num - the number of entered dates, dates - pointer to pointers to structs of dates 
void sort_dates(int* date_num, Date** dates){ 

    // Normalize the year 
    int d; // The date 
    for(d=0;d<*date_num;d++){ 
     if(dates[d]->year >= 90 && dates[d]->year <= 99){ 
      dates[d]->year = (dates[d]->year)+1900; 
     } else{ 
      dates[d]->year = (dates[d]->year)+2000; 
     } 
    } 

    qsort(dates[0], *date_num, sizeof(Date), compare); 

} 

int compare(const void* a, const void* b){ 

    Date* date1 = (Date*)a; 
    Date* date2 = (Date*)b; 

    // Concatenate year, month and day 
    long num1 = date1->year; 
    long num2 = date2->year; 

    // Concatenate month 
    num1 = num1*100+(date1->month); 
    num2 = num2*100+(date2->month); 

    // Concatenate day 
    num1 = num1*100+(date1->day); 
    num2 = num2*100+(date2->day); 

    printf("num1 = %d %d %d, num2 = %d %d %d\n", date1->year, date1->month, date1->day, date2->year, date2->month, date2->day); 

    //return (num2 - num1); 
    return 0; // Sorting Temporarily disabled 

} 

Nach Eingabe:

January 1 01 
January 1 00 
February 28 99 
July 17 12 
September 10 12 
July 1 00 
June 30 90 
August 25 06 
May 27 08 
October 1 03 

Das Programm konvertiert Monatsnamen zu Nummern und speichert Datumsangaben in Date** dates. Danach Ausführung erwarte ich so etwas wie dies im Format num1 = year month day, num2=year month day:

num1 = 2001 1 1, num2 = 2012 9 10 
num1 = 2012 9 10, num2 = 2000 7 1 
... 

Aber es gibt tatsächlich so etwas wie die:

num1 = 2001 1 1, num2 = 0 0 0 
num1 = 0 2000 1, num2 = 33 0 0 
num1 = 1 0 33, num2 = 0 2000 1 
num1 = 2001 1 1, num2 = 1 0 33 
num1 = 0 0 0, num2 = 1 0 33 
num1 = 2 28 0, num2 = 0 0 1999 
num1 = 2012 7 17, num2 = 0 0 0 
num1 = 0 33 0, num2 = 2012 7 17 
num1 = 2 28 0, num2 = 0 33 0 
num1 = 0 0 1999, num2 = 0 33 0 
num1 = 2001 1 1, num2 = 2 28 0 
num1 = 0 0 0, num2 = 2 28 0 
num1 = 1 0 33, num2 = 2 28 0 
num1 = 0 2000 1, num2 = 2 28 0 
num1 = 33 0 0, num2 = 2 28 0 

Ich vermute, dass es ein Problem mit der Größe jeden Block sein könnte als ex sortiert werden. Jahr ist in einigen Elementen in falscher Position (anders als zuerst), aber logisch scheint es richtig zu sein.

+0

sollte es nicht sein 'sizeof (* Datum)' –

+1

@PeterMiehle Das ist ein Syntaxfehler. :) Vielleicht hast du 'sizeof (Date *)' gemeint. – unwind

+0

upps sorry, zu viel golang –

Antwort

2

Dies:

qsort(dates[0], *date_num, sizeof(Date), compare); 

ist falsch, wenn Sie dates dann dates zu qsort() passieren, nicht sein erstes Element sortieren möchten. Die Größe, die Sie sortieren möchten, ist auch die Größe eines Zeigers, d. H. sizeof (Date *) oder immer besser sizeof *dates.

Ferner berücksichtigt Ihre Vergleichsfunktion nicht, dass Zeiger auf Elemente von übergeben werden, d.h. Zeiger auf Zeiger auf Date. Das bedeutet, es beginnen sollte:

static int compare(const void* a, const void* b){ 
    const Date * const date1 = *(const Date**) a; 
    const Date * const date2 = *(const Date**) b; 

Auch diese Änderung, da die Vergleichsfunktion zu qsort() benötigt wird, zwei Zeiger auf Elemente in dem Array übergeben wird, die sortiert wird immer. Das ist eine vernünftige Sache, sie kann die Elemente selbst nicht passieren (sie kennt ihre Typen nicht), aber eine const void * kann auf jede Art von Daten zeigen. Da Ihre Array-Elemente vom Typ Date * (Zeiger auf Date) sind, bedeutet dies, dass die tatsächlichen Werte, die an compare() gesendet werden, Zeiger auf Zeiger auf Date sind (d. H. Date **).

Schließlich ist es sinnlos, const hineinzulassen, also tun Sie das nicht.

+0

Um den letzten Absatz zu verdeutlichen: 'Datum * Datum1 = (Datum *) a;' sollte sein Datum * Datum1 = * (Datum **) a; ' – user694733

+0

Ja, es funktioniert, Danke ! Kannst du mir erklären, wie diese Änderungen in der 'compare' Funktion funktionieren? Es ist so verwirrend für mich – Jojko

+0

@Jojko Ich habe versucht, ein paar Worte mehr hinzuzufügen. – unwind

Verwandte Themen