Forum: Compiler & IDEs Qsort funktioniert nicht ordnungsgemäß


von Emila (Gast)


Lesenswert?

1
har **store(char **storrage, long *length, char *item);
2
int compare(const void*aa, const void*bb);
3
4
int main()
5
{
6
    char **mem_strings = NULL;
7
    long length = 0;
8
9
    mem_strings = store(mem_strings, &length, "Eins");
10
    mem_strings = store(mem_strings, &length, "Zwei");
11
    mem_strings = store(mem_strings, &length, "Drei");
12
    mem_strings = store(mem_strings, &length, "Vier");
13
    mem_strings = store(mem_strings, &length, "Fuenf");
14
    mem_strings = store(mem_strings, &length, "Sechs");
15
16
    int (*compar)(const void *a,const void *b);
17
    compar = compare;
18
    qsort(mem_strings[0], 6, sizeof(char*), compar);
19
    printf("\n");
20
    //Ausgabe:
21
    int i;
22
    for(i = 0; i < length ;i++)
23
        printf("%s\n", mem_strings[i]);
24
    printf("\n\n");
25
    //######################################
26
27
    return 0;
28
}
29
30
int compare(const void *aa, const void *bb){
31
    char a = (char) (*((int *)aa));
32
    char b = (char) (*((int *)bb));
33
    printf("%c \n%c\n\n", a, b);
34
    return a - b;
35
}
36
37
char **store(char **storrage, long *length, char *item){
38
39
    static long size_s = 0;
40
    size_s += 1;
41
    char **backupStorrage = storrage;
42
    if( (storrage = realloc(storrage, size_s * sizeof(char*))) == NULL){
43
        printf("Speicher konnte nicht erfolgreich alloziiert werden!\n");
44
        return backupStorrage;
45
    }
46
    else{
47
        (*length)++;
48
        printf("%ld\n", *length);
49
        printf("Speicher erfolgreich alloziiert!\n");
50
        storrage[size_s-1] = item;
51
    }
52
    return storrage;
53
}

Irgendwie funktioniert das nicht ganz. Ich frag mich nur wieso. Das 
Qsort übergibt als zweiten Buchstaben das klein i nach dem e vom Einser, 
was aber nicht so sein soll. Ich habe auch ausdrücklich geschrieben

qsort(mem_strings[0]...

das heißt das Qsort sollte eigentlich jedes char*, sprich jede 
Anfangsadresse des nächsten Strings übergeben, was es aber nicht tut. 
Ich frage mich aber wieso das so ist?

Ich bin dankbar für jede Hilfe!

von Yalu X. (yalu) (Moderator)


Lesenswert?

Was willst du sortieren, die Strings in mem_strings oder die einzelnen
Zeichen in mem_strings[0] ("Eins")? Dein Code enthält Hinweise auf
beides, macht aber keins von beidem richtig.

Edit: Falls die Strings sortiert werden sollen, nach welchem Kriterium
soll dies geschen? Lexikographisch oder nur nach dem Anfangsbuchstaben?

von Emila (Gast)


Lesenswert?

Yalu X. schrieb:
> Edit: Falls die Strings sortiert werden sollen, nach welchem Kriterium
> soll dies geschen? Lexikographisch oder nur nach dem Anfangsbuchstaben?

Genau, ich will sie nach Anfangsbuchstaben sortieren. Ich habe der 
FUnktion compare getestet und ihr folgende Werte übergeben:
1
compare(mem_strings[0], mem_strings[1])
2
compare(mem_strings[2], mem_strings[3])
usw.. und erhalte nach konvertierung:
1
int compare(const void *aa, const void *bb){
2
    char a = (char) (*((int *)aa));
3
    char b = (char) (*((int *)bb));
4
    printf("%c \n%c\n\n", a, b);
5
    return a - b;
6
}

immer nur die Anfangsbuchstaben, also wie gewollt! An der Funktion 
Compare kann es also nicht liegen.

Dh im Qsort muss irgendetwas nicht stimmen...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Der erste Parameter bei Deinem qsort-Aufruf ist ziemlich sicher nicht 
das, was Du da haben möchtest.

Lass mal die [0] weg.

von Amateur (Gast)


Lesenswert?

Eine wahrscheinlich fehlerfrei funktionierende Funktion wie qsort, 
entbindet Dich nicht davon genau zu spezifizieren, was und wie sortiert 
werden soll.
Also ob "Zweifel" größer als "Zett" - oder etwa gleich - wg. [0].
Und natürlich die Abfragefunktion richtig zu implementieren.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Der Aufruf von qsort ist fehlerhaft. Du willst das Array mem_strings
sortieren und nicht nur dessen erstes Element. Deswegen:

Rufus Τ. Firefly schrieb:
> Lass mal die [0] weg.

Die compare-Funktion stimmt dann auch nicht. Die übergebenen Argumente
sind Pointer auf char-Pointer, die ihrerseits Strings repräsentieren,
d.h. auf das jeweils erste Zeichen des Strings zeigen.

Folglich werden a und b wie folgt bestimmt:
1
    //       |-- String --| v-- Index 0 -> erstes Zeichen
2
    char a = (*(char **)aa)[0];
3
    char b = (*(char **)bb)[0];

oder auch einfach
1
    char a = **(char **)aa;
2
    char b = **(char **)bb;

von Emila (Gast)


Lesenswert?

Danke vielmals!!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.