2016-09-07 1 views
1

Ich versuche Wörter aus einer Datei in einen Binärbaum einzufügen. Die Einfügefunktion funktioniert, wenn ich nicht aus einer Datei lese, auch wenn ich versuchte, jeden gelesenen String nach fscanf zu drucken es funktioniert auch, aber wenn ich versuche, es in einen Baum einzufügen, wird nur der letzte String aus einer Datei gelesen. Warum passiert das?Fscanf liest nur ein letztes Wort aus einer Datei

while(1){ 

    if(fscanf(f,"%s %d",string,&x)==EOF) 
      break; 

     tree=insert(tree,string,x); 
    } 
+1

Sie machen keine Kopie von 'string' bevor Sie es einfügen. Die 'insert'-Funktion speichert nur einen Zeiger, und alle Baumeinträge zeigen auf denselben String. – Barmar

+0

Bitte geben Sie ein vollständiges Beispielprogramm an, das den Fehler zeigt, damit wir nicht raten, wie der Rest Ihres Codes aussieht. –

Antwort

1

insert() keine Kopie des Strings machen, es speichert nur den Zeiger Sie es in dem Baum geben. Alle Baumeinträge enthalten also einen Zeiger auf die gleiche Zeichenfolge, die Sie jedes Mal überschreiben, wenn Sie fscanf aufrufen.

Das gleiche Problem passiert mit dem x Argument, Sie übergeben den gleichen Zeiger jedes Mal. Sie müssen für jeden der Werte auch einen neuen int zuweisen.

while (1) { 
    if (fscanf(f, "%s %d", string, x) == EOF) { 
     break; 
    } 
    char *new_str = malloc(strlen(string)+1); 
    strcpy(new_str, string); 
    int *new_int = malloc(sizeof(*x)); 
    *new_int = *x; 
    tree = insert(tree, new_str, new_int); 
} 
+0

Dies wird immer das gleiche 'int *' einfügen. –

+0

@RolandIllig Nein, wird es nicht. Ganzzahlen werden nach Wert an Funktionen übergeben. – Barmar

+0

Aber 'x' ist kein' int', es ist ein 'int *'. Andernfalls würde der Aufruf von 'fscanf' undefiniertes Verhalten auslösen. –

0

Der Code sollte wie folgt aussehen:

while (fscanf(f, "%s %d", string, &val) == 2) { 
    char *copy = malloc(strlen(string) + 1); 
    if (copy == NULL) 
     break; 
    strcpy(copy, string); 
    insert(copy, val); 
} 

Hinweis den Fehler für fscanf Handhabung, der prüft, ob beide Felder gelesen werden konnte. Beachten Sie auch die & vor val, die wahrscheinlich eine Compiler-Warnung verhindert. Übrigens sollten Sie alle verfügbaren Compiler-Warnungen aktivieren, damit Sie nicht selbst nach den Fehlern suchen müssen.

+0

Das zweite Argument von 'insert()' sollte 'int *' sein, Sie übergeben 'int'. – Barmar

+0

Ich denke, das Einfügen des "Int" ist in diesem Fall sinnvoller, obwohl das aus der Frage nicht klar ist. –

+0

Der Baum könnte so entworfen werden, dass jede Art von Daten gespeichert werden kann, so dass der Wert "void *" wäre. – Barmar

Verwandte Themen