Metalmind Geschrieben 10. Mai 2010 Geschrieben 10. Mai 2010 Hallo Leute, ich habe ein Verständnisproblem mit dem qsort() -Algorithmus ich habe ein Array1[] = {"ca", "ab", "ba, "cb"} und möchte diese 4 Elemente nun alphabetisch sortieren Folgendes Schema habe ich für den comparator auf einer Seite gefunden, leider scheitere ich daran diese Funktion meinen Anforderungen anzupassen... scmp( void *sp1, void *sp2 ) { return( strcmp(*(char **)sp1, *(char **)sp2) ); } Kann mir jemand bitte den Gedankengang hinter dieser Funktion erklären und was ich dort einsetzen muss damit mein qsort() Algorithmus funktioniert? Meine weitere Funktion sieht danrunter so aus: int n; int main () { qsort (Array, 4, sizeof(char), scmp); //der Quicksort-Algorithmus for (n=0; n<6; n++) //Ausgabe der Daten printf ("%d ",values[n]); return 0; } Vielen Dank Gruß Metalmind Zitieren
Klotzkopp Geschrieben 10. Mai 2010 Geschrieben 10. Mai 2010 sizeof(char) ist Unsinn, deine Array-Elemente sind (vermutlich) char*, nicht char. Zitieren
Metalmind Geschrieben 11. Mai 2010 Autor Geschrieben 11. Mai 2010 Tut mir leid, aber ich kenne den Unterschied zwischen char und char* nicht, könntest du mir das bitte erklären? Mein eigendliches Problem ist ja eigendlich, was ich in das Grundgerüst scmp( void *sp1, void *sp2 ) { return( strcmp(*(char **)sp1, *(char **)sp2) ); } einfügen muss, damit die untere Funktion funktioniert Zitieren
Klotzkopp Geschrieben 11. Mai 2010 Geschrieben 11. Mai 2010 Tut mir leid, aber ich kenne den Unterschied zwischen char und char* nicht, könntest du mir das bitte erklären?Weißt du, was Zeiger sind? Variablen vom Datentyp char repräsentieren ein Zeichen. Der Typ char* ist ein Zeiger auf char. In C benutzt man char-Arrays und char-Zeiger als Strings. Mein eigendliches Problem ist ja eigendlich, was ich in das Grundgerüst scmp( void *sp1, void *sp2 ) { return( strcmp(*(char **)sp1, *(char **)sp2) ); } einfügen muss, damit die untere Funktion funktioniertGar nichts, der Teil sieht gut aus. Zitieren
Schandfleck Geschrieben 11. Mai 2010 Geschrieben 11. Mai 2010 ich habe ein Array1[] = {"ca", "ab", "ba, "cb"} bei "ab fehlt ein schliessendes " scmp( void *sp1, void *sp2 ) { return( strcmp(*(char **)sp1, *(char **)sp2) ); } streng genommen int scmp(const void *sp1, const void *sp2) { return strcmp(*(const char **)sp1, *(const char **)sp2); } int n; int main () { qsort (Array, 4, sizeof(char), scmp); //der Quicksort-Algorithmus Dein Array heißt Array1, es enthält char* qsort(Array1, 4, sizeof (char *), scmp); int n; for (n=0; n<6; n++) //Ausgabe der Daten Du hast nur vier Elemente im Array printf ("%d ",values[n]); Array1, nicht values Insgesamt sollte es etwa so aussehen: #include <stdio.h> #include <stdlib.h> char *Array1[] = {"ca", "ab", "ba", "cb"}; int scmp(const void *sp1, const void *sp2) { return strcmp(*(const char **)sp1, *(const char **)sp2); } int main(int argc, char **argv) { int n; qsort(Array1, 4, sizeof (char *), scmp); for (n=0; n<4; n++) printf("%s ", Array1[n]); return 0; } Zitieren
Metalmind Geschrieben 14. Mai 2010 Autor Geschrieben 14. Mai 2010 Okay, danke euch zwei für die viele Hilfe, das int scmp(const void *sp1, const void *sp2) { return strcmp(*(const char **)sp1, *(const char **)sp2); } kommt mir auch gleich bekannter vor, aber dass ich dachte das wäre eine allgemeine Formel zeigt wohl dass ich das noch nicht so ganz verstanden habe, könnte mir bitte jemand die Bedeutung des Codes erklären? Zitieren
Schandfleck Geschrieben 19. Mai 2010 Geschrieben 19. Mai 2010 Okay, danke euch zwei für die viele Hilfe, das int scmp(const void *sp1, const void *sp2) { return strcmp(*(const char **)sp1, *(const char **)sp2); } Das const, das ich eingefügt habe, bedeutet lediglich, daß der betreffende Wert, in diesem Fall das Ziel des doppelten Zeigers, nicht verändert werden kann. Da qsort() von der Vergleichsfunktion erwartet, daß diese die Werte nicht verändert, sollte sie entsprechend deklariert seien; anderenfalls gibt es eine Warnung wegen des nicht passenden Typs. Typdeklarationen in C liest man am Besten so, als würde die Variable benutzt. Beispiel, wenn Du unsicher bist, was sp in »const char **sp« für einen Typ ist, fang mit sp an. Darauf wird der Dereferenzierungsoperator (*) angewandt. sp muß also schonmal ein Zeiger auf irgendetwas seien. Dann folgt ein weiteres Sternchen. *sp ist also auch ein Zeiger, sp somit ein Zeiger auf ein Zeiger. char **sp gibt nun an, daß **sp ein char ist. Somit ist sp ein Zeiger auf einen Zeiger auf ein Char. Das zusätzliche const heißt nun, das der Wert unveränderbar ist. Beachte, daß sich das const nur auf den Char bezieht, auf den **sp zeigt. Die Zeiger *sp und sp dürfen durchaus verändert werden. Interessant ist die Deklaration der Funktion qsort() void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)) Das vierte Argument heißt compar und ist ein Zeiger auf eine Funktion, die zwei Zeiger auf einen konstanten Wert unbekannten Typs als Argument hat, und einen Integer als Ergebnis liefert. Klar? Zitieren
Metalmind Geschrieben 25. Mai 2010 Autor Geschrieben 25. Mai 2010 wozu braucht man denn die vielen Zeiger überhaupt? würde: scmp( void sp1, void sp2 ) { return( strcmp(char sp1, (char sp2) ); } nicht auch reichen? (bitte beachten dass ich keine Ahnung hab was ich da grad geschrieben hab) Zitieren
Klotzkopp Geschrieben 26. Mai 2010 Geschrieben 26. Mai 2010 wozu braucht man denn die vielen Zeiger überhaupt? qsort muss Arrays von allen möglichen Dingen sortieren können. Die Arrayelemente können ganz unterschiedliche Größen haben, je nachdem, was man da sortiert. Zeiger sind immer gleich groß. Daher übergibt man die Adressen zweier zu vergleichender Elemente als untypisierter Zeiger, das ist eben void*. In der Vergleichsfunktion müssen diese Elementzeiger dann auf den richtigen Typ gecastet werden. In deinem Fall hast du ein Array von char-Zeigern. Die Vergleichsfunktion wird mit den Adressen dieser Elemente aufgerufen, also kommen char-Zeiger-Zeiger rein (char**) Zitieren
Metalmind Geschrieben 27. Mai 2010 Autor Geschrieben 27. Mai 2010 Hallo, Leute, mein Programm schreitet voran, ich habe nun aber ein Problem mit mehrdimensionalen Arrays mein Programm sieht so aus: #include <stdio.h> int Nr[100][20]; int SerienNr[100][20]; char Bezeichnung[100][20]; int TeileNr[100][20]; int Lagerbestand[100][20]; char verfahren; char kriterium; int i; int j; int main (void) { FILE *data1; data1 = fopen("C:/test.txt","r+"); //Datei text.txt wird zum lesen und schreiben geöffnet for (i=0;i<10;i++) { fscanf(data1,"%s %s %s %s %s",&Nr,&SerienNr,&Bezeichnung,&TeileNr, &Lagerbestand); } for (i=0;i<10;i++) { for (j=0;j<10;j++) { if(TeileNr==TeileNr[j]); { Lagerbestand=Lagerbestand+Lagerbestand[j]; //ab hier Nr[j]=0; SerienNr[j]=0; Bezeichnung[j]="0"; TeileNr[j]=0; Lagerbestand[j]=0; //bis hier } } } system ("PAUSE"); return 0; } Innerhalb der if-Schleife bekomme ich nun Compilerfehler, ich denke es liegt daran dass ich etwas bei der Veränderung der mehrdimensionalen Arrays falsch gemacht habe, könnte mir bitte jemand sagen was ich in diesem Fall tun muss? Zitieren
Klotzkopp Geschrieben 27. Mai 2010 Geschrieben 27. Mai 2010 Hallo, Leute, mein Programm schreitet voran, ich habe nun aber ein Problem mit mehrdimensionalen ArraysFür neue Probleme mach bitte in Zukunft einen neuen Thread auf. Ein Thread pro Thema, nicht pro Benutzer oder Programm. Das hat ja nun nichts mehr mit Quicksort zu tun. Zum eigentlichen Problem: Warum sind deine int-Arrays denn überhaupt zweidimensional? Welche Bedeutung hat die zweite Dimension? Bei den char-Arrays kann ich es ja noch verstehen, aber bei int? Zitieren
Metalmind Geschrieben 27. Mai 2010 Autor Geschrieben 27. Mai 2010 Okay, das war dann wohl einfach ein überbleibsel, vorher waren alle Typ char. Damit bleibt nurnoch die Zeile Bezeichnung[j]="0"; als Problemverursacher übrig, meiner Meinung nach müsste das so funkionieren, mein Compiler sagt aber: error: incompatible types in assignment Zitieren
Klotzkopp Geschrieben 27. Mai 2010 Geschrieben 27. Mai 2010 Man kann Arrays nichts zuweisen. Im allgemeinen Fall kopiert man Arrays Element für Element, mit einer Schleife. C-Strings (char-Arrays) kopiert man mit strcpy. Zitieren
Metalmind Geschrieben 27. Mai 2010 Autor Geschrieben 27. Mai 2010 Ich habe nun aus den zweidimensionalen int-Arrays eindimensionale gemacht, allerdings kommt jetzt nurnoch Matsch dabei raus wenn ich mit fscanf(data1,"%s %s %s %s %s",&Nr,&SerienNr,&Bezeichnung,&TeileNr, &Lagerbestand); die Daten aus einer Datei in den Arrays speichern möchte, allerdings fällt mir kein anderer Weg ein die (Zahlen)strings aus der Datei zu speichern als durch %s, wenn ich dies in ein int Array speichere und es ausgeben möchte kommen dort immer falsche Werte raus Zitieren
Klotzkopp Geschrieben 27. Mai 2010 Geschrieben 27. Mai 2010 allerdings fällt mir kein anderer Weg ein die (Zahlen)strings aus der Datei zu speichern als durch %s, wenn ich dies in ein int Array speichere und es ausgeben möchte kommen dort immer falsche Werte rausDu liest da gar nicht in int-Arrays ein. SerienNr mag ein int-Array sein, aber SerienNr ist ein einzelner int, und die liest man z.B. mit %d ein. Zitieren
Metalmind Geschrieben 27. Mai 2010 Autor Geschrieben 27. Mai 2010 Ich habe es jetzt mit int Nr[100]; int SerienNr[100]; char Bezeichnung[100][20]; int TeileNr[100]; int Lagerbestand[100]; fscanf(data1,"%d %d %s %d %d",&Nr,&SerienNr,&Bezeichnung,&TeileNr, &Lagerbestand); versucht, bei Nr[0] sollte eigendlich 1 herrauskommen, es wird aber 4219652 (und ähnliche Werte bei allen int-Zahlen) ausgegeben, das einzige funktionierende ist Bezeichnung Zitieren
Klotzkopp Geschrieben 27. Mai 2010 Geschrieben 27. Mai 2010 es wird aber 4219652 (und ähnliche Werte bei allen int-Zahlen) ausgegeben, das einzige funktionierende ist Bezeichnung Ich sehe im gezeigten Code keine Ausgabe. Wie gibst du denn aus? Zitieren
Metalmind Geschrieben 27. Mai 2010 Autor Geschrieben 27. Mai 2010 for (i=0;i<10;i++) { printf("%d %d %s %d %d\n",&Nr,&SerienNr,&Bezeichnung,&TeileNr, &Lagerbestand); } Zitieren
Klotzkopp Geschrieben 27. Mai 2010 Geschrieben 27. Mai 2010 Lass bei den ints die & weg, sonst gibst du nur deren Adressen aus. Zitieren
Metalmind Geschrieben 27. Mai 2010 Autor Geschrieben 27. Mai 2010 Danke für die Geduld, das hilfe mir ungemein weiter! Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.