Kadaj Geschrieben 26. Februar 2012 Teilen Geschrieben 26. Februar 2012 Hallo, ich versuche grad ein Programm zu schreiben, welches Namen von stdin einliest und diese dann in eine, von mir angelegte Struktur, einsortiert. Diese Daten lasse ich nach jedem Schreiben ausgeben und am Ende. So richtig funktioniert das aber noch nicht, ich fummel schon eine Weile am Code herum, aber es wird nicht besser. Hier erstmal der Quellcode: #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct sort { char *data; struct sort *l; struct sort *r; }sort; sort *tree; sort init={}; void add(sort *tree,char *data) { if(tree->data==NULL) { tree->data=data; } else { if(strcmp(data,tree->data)<0) // data ist kleiner, nach links { // rücke nach links if(tree->l==NULL) { tree->l=malloc(sizeof(sort)); // Speicher reservieren *(tree->l)=init; // initialisieren mit struct sort } add(tree->l,data); // Rekursion, bis Elememt eingetragen wird } else // data ist größer, also nach rechts damit { if(tree->r==NULL) { tree->r=malloc(sizeof(sort)); // Speicher reservieren *(tree->r)=init; // initialisieren mit struct sort } add(tree->r,data); // Rekursion, bis Elememt eingetragen wird } } printf("bisheriger Baum:\n"); printtree(tree); } void log(FILE *file) { if(tree->data!=NULL) // Name vorhanden? { fprintf(file,tree->data); // Name nach stdout schreiben log(tree->r); // Funktion rekursiv für rechtes Element aufrufen log(tree->l); // Funktion rekursiv für linkes Element aufrufen } } int main(int argc,char *argv[]) { FILE *file; // Pointer für Logfile char puffer[64]; // Array für Namens-Eingabe tree=malloc(sizeof(sort)); // Speicher reservieren *tree=init; // initialisieren mit struct sort if(argc!=2) { perror("usage: <program> <logfile>"); exit(EXIT_FAILURE); } file=fopen(argv[1],"a+t"); if(file==NULL) { perror("erro: open file"); exit(EXIT_FAILURE); } while(strcmp(puffer,"qq")!=0) { printf("Geben Sie einen Namen ein. Zum Beenden 'qq' eingeben:\n"); fgets(puffer,64,stdin); puffer[strlen(puffer)-1]=0; if(strcmp(puffer,"qq")!=0) add(tree,puffer); } printf("Hier die Ausgabe für den gesamten Baum:\n"); printtree(tree); log(file); // Baum in die Logfile schreiben fclose(file); return 0; } [/PHP] Also, das Programm sortiert die Namen alphabetisch wie in einem Binärbaum ein. Soll es zumindest, das passiert, wenn ich es ausführe: [PHP] ./tree log.txt Geben Sie einen Namen ein. Zum Beenden 'qq' eingeben: Anna bisheriger Baum: Anna Geben Sie einen Namen ein. Zum Beenden 'qq' eingeben: Bob bisheriger Baum: Bob bisheriger Baum: Bob Bob Geben Sie einen Namen ein. Zum Beenden 'qq' eingeben: qq Hier die Ausgabe für den gesamten Baum: qq qq Speicherzugriffsfehler Er scheint die schon vorhandenen structs in data immer mit der aktuellen Eingabe zu überschreiben, keine Ahnung wieso. Der Speicherzugriffsfehler kommt vom schreiben in die Datei, da haut auch was noch nicht so richtig hin. Sieht jemand warum das Einsortieren nicht funktioniert? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 26. Februar 2012 Teilen Geschrieben 26. Februar 2012 Überleg mal genau, wohin der Zeiger in deiner Struktur zeigt. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kadaj Geschrieben 26. Februar 2012 Autor Teilen Geschrieben 26. Februar 2012 Moment, ich seh grade, dass ich eine Funktion nicht mit rüber kopiert ( printtree ) habe, wie ungeschickt. So sieht es vollständig aus: #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct sort { char *data; struct sort *l; struct sort *r; }sort; sort *tree; sort init={}; void add(sort *tree,char *data) { if(tree->data==NULL) { tree->data=data; } else { if(strcmp(data,tree->data)<0) // data ist kleiner, nach links { // rücke nach links if(tree->l==NULL) { tree->l=malloc(sizeof(sort)); // Speicher reservieren *(tree->l)=init; // initialisieren mit struct sort } add(tree->l,data); // Rekursion, bis Elememt eingetragen wird } else // data ist größer, also nach rechts damit { if(tree->r==NULL) { tree->r=malloc(sizeof(sort)); // Speicher reservieren *(tree->r)=init; // initialisieren mit struct sort } add(tree->r,data); // Rekursion, bis Elememt eingetragen wird } } printf("bisheriger Baum:\n"); printtree(tree); }void printtree(sort *tree) { if(tree) // Name vorhanden? { puts(tree->data); // Name nach stdout schreiben printtree(tree->r); // Funktion rekursiv für rechtes Element aufrufen printtree(tree->l); // Funktion rekursiv für linkes Element aufrufen } } void log(FILE *file) { if(tree->data!=NULL) // Name vorhanden? { fprintf(file,tree->data); // Name nach stdout schreiben log(tree->r); // Funktion rekursiv für rechtes Element aufrufen log(tree->l); // Funktion rekursiv für linkes Element aufrufen } } int main(int argc,char *argv[]) { FILE *file; // Pointer für Logfile char puffer[64]; // Array für Namens-Eingabe tree=malloc(sizeof(sort)); // Speicher reservieren *tree=init; // initialisieren mit struct sort if(argc!=2) { perror("usage: <program> <logfile>"); exit(EXIT_FAILURE); } file=fopen(argv[1],"a+t"); if(file==NULL) { perror("erro: open file"); exit(EXIT_FAILURE); } while(strcmp(puffer,"qq")!=0) { printf("Geben Sie einen Namen ein. Zum Beenden 'qq' eingeben:\n"); fgets(puffer,64,stdin); puffer[strlen(puffer)-1]=0; if(strcmp(puffer,"qq")!=0) add(tree,puffer); } printf("Hier die Ausgabe für den gesamten Baum:\n"); printtree(tree); log(file); // Baum in die Logfile schreiben fclose(file); return 0; } [/PHP] Überleg mal genau, wohin der Zeiger in deiner Struktur zeigt. Wenn ich nur deinen Blick hätte ... Nun, in der Funktion add wird überprüft ob ein Eintrag in der übergebenen Struktur von Typ sort in data vorhanden ist. Wenn nicht, dann wird dem Zeiger auf data(in der Struktur) den Wert von data(des Array zugewiesen) ... Ich glaub ich versteh nicht worauf du hinaus willst. In meiner Struktur sort hab ich einen Zeiger auf ein char-Array für die Namen und jeweils 2 auf genau die selbe Struktur sort, einmal für links und einmal für rechts. Ich seh nichts, was ich falsch dereferenziert haben könnte... hmmm... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 27. Februar 2012 Teilen Geschrieben 27. Februar 2012 Du setzt den data-Zeiger deiner Struktur immer wieder auf die Speicheradresse des Arrays puffer in main. Alle deine data-Zeiger verweisen also auf denselben Speicherbereich. Daher ändert jede neue Eingabe alle Einträge im Baum. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kadaj Geschrieben 27. Februar 2012 Autor Teilen Geschrieben 27. Februar 2012 Ei, danke dir, daran hab ich ja garnicht gedacht. Ich dachte, das wäre richtig, weil ich mir den Inhalt des Pointers probehalber gleich hab ausgeben lassen. Dann muss ich ja einfach nur beide Pointer bei der Zuweisung dereferenzieren: { *(tree->data)=*data; printf("datapointer nach füllen:\n %s \n",*(tree->data)); } [/PHP] Scheinbar habe ich Pointerarithmetik noch nicht ganz verstanden, denn nun ist meine Ausgabe: [PHP] # ./tree log Geben Sie einen Namen ein. Zum Beenden 'qq' eingeben: Anna data-array:Anna data-pointer:(null) Speicherzugriffsfehler Ich hab dem Pointer Speicher geserviert und den Wert von data zugewiesen, warum ist tree->data dann (null), :confused: das versteh ich grad nicht... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 27. Februar 2012 Teilen Geschrieben 27. Februar 2012 Dann muss ich ja einfach nur beide Pointer bei der Zuweisung dereferenzieren:Nein, damit kopierst du nur das erste Zeichen. Du kannst in C einen String nicht durch eine einfache Zuweisung kopieren, du musst strcpy benutzen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kadaj Geschrieben 10. März 2012 Autor Teilen Geschrieben 10. März 2012 Also nen Freund hat mir mal unter die Arme gegriffen, so sieht das Ergebnis aus: #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct sBinarySortedTree { char *data; struct sBinarySortedTree *left; struct sBinarySortedTree *right; }tBinarySortedTree; tBinarySortedTree init={0}; /* init vom Typ tBinarySortedTree mit 0 initialisieren */ tBinarySortedTree *create() { tBinarySortedTree *newTree = malloc(sizeof(tBinarySortedTree)); /* Speicher reservieren */ if( newTree ) *newTree = init; return newTree; } void tree_log( tBinarySortedTree *tree, FILE *file ) { if( !file || !tree ) return; tree_log( tree->left, file ); if( tree->data ) fprintf( file, "%s\n", tree->data ); tree_log( tree->right, file ); } void printTree( tBinarySortedTree *tree ) { tree_log( tree, stdout ); } void addName( tBinarySortedTree *tree, char *data ) { if( !tree || !data ) return; if(tree->data==NULL) { tree->data=data; } else { if(strcmp(data,tree->data)<0) /* data ist kleiner, nach links */ { if(tree->left==NULL) tree->left=create(); addName( tree->left, data ); } else /* data ist größer, also nach rechts damit */ { if(tree->right==NULL) tree->right=create(); addName( tree->right ,data ); } } } #define BUFF_SIZE 64 void createInputPuffer( char **puffer ) { *puffer = malloc( BUFF_SIZE * sizeof( char ) ); if( !(*puffer) ) { fprintf( stderr, "could not create puffer\n" ); exit(EXIT_FAILURE); } } int main(int argc,char *argv[]) { FILE *file; /* Pointer für Logfile */ char *puffer = 0; /* Array für Namenseingabe */ tBinarySortedTree *myTree = 0; /* Wurzel des Baumes */ if(argc!=2) { perror("usage: <program> <logfile>"); exit(EXIT_FAILURE); } myTree=create(); if( !myTree ) { fprintf(stderr,"error:create Tree\n"); exit(EXIT_FAILURE); } createInputPuffer( &puffer ); while(strcmp(puffer,"qq")!=0) { printf("Geben Sie einen Namen ein. Zum Beenden 'qq' eingeben:\n"); fgets(puffer,BUFF_SIZE,stdin); puffer[strlen(puffer)-1]=0; if(strcmp(puffer,"qq")!=0) { addName( myTree, puffer ); createInputPuffer( &puffer ); } } printf("\nHier die Ausgabe für den gesamten Baum:\n"); printTree( myTree ); file=fopen(argv[1],"a+"); if( !file ) { fprintf(stderr, "error: open file: %s\n",argv[1]); exit(EXIT_FAILURE); } tree_log( myTree, file ); fclose(file); return EXIT_SUCCESS; } [/PHP] Vielen Dank für die Hilfe Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
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.