Ordnen von Struct-Elementen



  • Hallo,

    ich bräuchte einen Rat zu folgendem Problem:

    Ich habe ein "Struct Array" nach folgendem Schema

    struct Test {
    int num;
    char name[40];
    char und[40];
    char weitere[40];
    };
    
    struct Test test[10];
    

    Ich würde nun gerne die Strukturen alphabetisch nach Namen sortieren (Element name). Dabei sollten alle zugehörigen Elemente ebenfalls mit verschoben werden.

    test[0].name sollte dann z.B. "abc" sein und test[1].name "def".

    Das Stichwort "strcmp()" kenne ich bereits, aber dieser Fall ist mir etwas zu komplex. Hat jemand eine Idee ?

    MfG. Hanz



  • Was ist daran jetzt kompliziert?

    Das vergleichen?
    Ja, dafür ist strcmp geeignet.

    Das umkopieren?
    structs kann man auch mit = zuweisen.

    Das sortiern?
    hast du denn schon eine Sortierfunktion?
    Kann auch eine für int sein.

    Du kannst dir auch mal die Funktion qsort ansehen.
    Die wurde extra für soetwas gemacht.
    Die macht das sortieren und umkopieren für dich. Der musst du nur eine geeignete Vergleichsfunktion mitgeben.



  • Ich komme leider gerade nicht mit qsort() weiter.

    int compare( void const * lhs, void const * rhs )
    {
      char * left  = *((char **) lhs);
      char * right = *((char **) rhs);
    
      return strcmp( left, right );
    }
    
    void ordnen(void) {
    
    int i;
    
    struct Test {
    int num;
    char name[40];
    char und[40];
    char weitere[40];
    };
    
    struct Test test[10];
    
    qsort(test, 10, sizeof(struct Test), compare);
    
        for (i=0; i<10; ++i) {
            printf("%d: %s\n", i, test[i].name);
    
    	}
    }
    

    Da ich noch nicht wirklich fit in Sachen Pointer bin, vermute ich den Fehler in der compare Funktion.
    Offiziell bekomme ich eine "Access Violation".

    Hat jemand einen Verbesserungsvorschlag ?

    MfG. Hanz



  • struct Test {
    int num;
    char name[40];
    char und[40];
    char weitere[40];
    };
    
    int compare( void const * lhs, void const * rhs )
    {
      struct Test * left  = (struct Test *) lhs);
      struct Test * right = (struct Test *) rhs);
    
      return strcmp( left->name, right->name );
    }
    
    void ordnen(void) {
    
    int i;
    
    struct Test {
    int num;
    char name[40];
    char und[40];
    char weitere[40];
    };
    
    struct Test test[10];
    
    qsort(test, 10, sizeof(struct Test), compare);
    
        for (i=0; i<10; ++i) {
            printf("%d: %s\n", i, test[i].name);
    
        }
    }
    


  • Läuft ! Vielen Dank ! 🙂



  • Ähh ... ja, die zweite Vereinbarung der Struktur (Z. 21 - 26) kann natürlich weg!



  • Wie du siehst, bekommt compare* zwei Zeiger auf die zu sortierenden Elemente.
    Jetzt kannst du compare noch aufbohren und bei Namensgleichheit noch weiter Vergleiche anstellen.

    *für den Test ist der Name in Ordnung. In einem richtigen Projekt solltest du den Namen anpassen. Z.B. compare_struct_Test


Anmelden zum Antworten