qsort



  • Ein char[4] ist nicht das selbe wie ein char*, das ist grob das Problem. Du interpretierst in cmp den String als Zeiger (jetzt unter der Annahme, dass sizeof(char*) == 4, sonst ist das noch ein bisschen wilder), und der endet natürlich im Nirvana.

    Was du in diesem speziellen Fall mit fester Stringlänge machen kannst, ist Folgendes:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main() {
      char trigram[][4] = { "foo", "bar", "baz", "qux", "abc" };
      int i;
    
      qsort(trigram, 5, 4, (int(*)(void const *, void const *)) strcmp); // Cast, um Compiler ruhigzustellen
    
      for(i = 0; i < 5; ++i) {
        puts(trigram[i]);
      }
    
      return 0;
    }
    


  • Danke! Hat pefekt geklappT


  • Mod

    Das geht auch ordentlich

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int strcmp_wrap(const void* s1, const void* s2)
    {
        return strcmp( s1, s2 );
    }
    
    int main() {
      char trigram[][4] = { "foo", "bar", "baz", "qux", "abc" };
      int i;
    
      qsort(trigram, 5, 4, strcmp_wrap);
    
      for(i = 0; i < 5; ++i) {
        puts(trigram[i]);
      }
    
      return 0;
    }
    


  • Könnte mir mal jemand den Cast erklären:

    [cpp]
    int compare(const void *a, const void *b){
        return(strcmp(*(const * char *)a, *(const * char *)b);
    }
    [/cpp]
    

    Intuitiv würde ich den cast so machen:

    [cpp]
    strcmp((const char *)a, (const char *)b);
    [/cpp]
    

  • Mod

    n0nam333 schrieb:

    Könnte mir mal jemand den Cast erklären:

    [cpp]
    int compare(const void *a, const void *b){
        return(strcmp(*(const * char *)a, *(const * char *)b);
    }
    [/cpp]
    

    Nein. Das funktioniert ja auch nicht. Wo kommt das überhaupt her?



  • camper schrieb:

    Das geht auch ordentlich

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int strcmp_wrap(const void* s1, const void* s2)
    {
        return strcmp( s1, s2 );
    }
    
    int main() {
      char trigram[][4] = { "foo", "bar", "baz", "qux", "abc" };
      int i;
    
      qsort(trigram, 5, 4, strcmp_wrap);
    
      for(i = 0; i < 5; ++i) {
        puts(trigram[i]);
      }
    
      return 0;
    }
    

    genau

    qsort(trigram, sizeof(trigram)/sizeof(trigram[0]), sizeof(char*), strcmp_wrap);
    


  • ochtnunk muss sein schrieb:

    genau

    qsort(trigram, sizeof(trigram)/sizeof(trigram[0]), sizeof(char*), strcmp_wrap);
    

    Na, Sorgfalt muss aber auch sein.

    sizeof(char*) ist in diesem Fall falsch, und sizeof(char[4]) ist immer 4. sizeof(*trigram) ginge.



  • camper schrieb:

    n0nam333 schrieb:

    Könnte mir mal jemand den Cast erklären:

    [cpp]
    int compare(const void *a, const void *b){
        return(strcmp(*(const * char *)a, *(const * char *)b);
    }
    [/cpp]
    

    Nein. Das funktioniert ja auch nicht. Wo kommt das überhaupt her?

    Ähm, doch der funktioniert. Kannst mir ja mal eine andere Lösung geben und mir die erklären.


  • Mod

    n0nam333 schrieb:

    camper schrieb:

    n0nam333 schrieb:

    Könnte mir mal jemand den Cast erklären:

    [cpp]
    int compare(const void *a, const void *b){
        return(strcmp(*(const * char *)a, *(const * char *)b);
    }
    [/cpp]
    

    Nein. Das funktioniert ja auch nicht. Wo kommt das überhaupt her?

    Ähm, doch der funktioniert. Kannst mir ja mal eine andere Lösung geben und mir die erklären.

    Nein, das funktioniert nicht. Welcher Compiler schluckt das?



  • gcc


  • Mod

    n0nam333 schrieb:

    gcc

    Kein neuerer. Und damit meine ich einen der letzten paar Jahre. Welcher soll das schlucken?

    edit: Und um die Ursprungfrage nochmal deutlich zu beantworten: Das kann man nicht erklären, außer dass es falsch ist und keinen Sinn macht. Da steht nämlich übersetzt: Caste zu a zu einem Zeiger auf einen char der ein Zeiger auf const ist. Und wie du merkst, ist das ziemlicher Unsinn.



  • Ich behaupte mal ganz dreist, dass kein C-Compiler, ganz gleich welchen Jahrzehnts, das je geschluckt hat. Es gibt stumpf keine sinnvolle Möglichkeit, das zu parsen.

    Wenn, wie ich vermute, (const char **) gemeint ist, greift das schon genannte Problem, dass a und b nicht auf Zeiger zeigen -- Arrays sind halt keine Zeiger.


Anmelden zum Antworten