2016-10-26 6 views
0

Ich lese aus einer Datei und versuche, sie in eine verknüpfte Liste einzufügen und dann durch die verknüpfte Liste zu gehen, um den Inhalt auszudrucken. Ich habe ein wenig Probleme, da meine Ausgabe nicht die gesamte verknüpfte Liste, sondern nur das letzte Element mehrfach druckt. Ich habe den Code unten gepostet und ich habe nur Snippets gepostet und die Fehlerüberprüfung aus Platzgründen entfernt.C Drucken einer verknüpften Liste funktioniert nicht?

typedef struct Node{ 
    char* data; 
    struct Node* next; 
} NODE; 

NODE* head = NULL; 
NODE* tail = NULL; 

int main(int argc, char* argv[]) 
{ 
    char buffer[1024]; 
    FILE* fp = fopen(argv[1], "r"); 
    while(fscanf(fp, "%1023s", buffer) == 1) 
    { 
     addNode(buffer); 
    } 
    print_linked_list(head); 
    return 0; 
} 

void print_linked_list(NODE* head) 
{ 
    NODE* ptr = head; 
    while(ptr != NULL) 
    { 
     printf("%s ", ptr -> data); 
     ptr = ptr -> next; 
    } 
} 

void addNode(char* str) 
{ 
    NODE* newNode = createNode(str); 
    if(head == tail && tail == NULL) 
    { 
     head = newNode; 
     tail = newNode; 
     head -> next = NULL; 
     tail -> next = NULL; 
    } 
    else 
    { 
     tail -> next = newNode; 
     tail = newNode; 
     tail -> next = NULL; 
    } 
} 

NODE* createNode(char* str) 
{ 
    NODE* newNode = malloc(sizeof(NODE)); 
    newNode -> data = malloc((1 + strlen(str)) * sizeof(char)); 
    newNode -> data = str; 
    newNode -> next = NULL; 
    return newNode; 
} 

Also, wenn eine Datei enthält einen Text wie „How are you“, ich meine Ausgabe gedruckt werden wie „Wie geht es Ihnen“ erwartet, aber alles, was ich bekommen ist „du du du“. Wie behebe ich das?

Antwort

2

Bei

newNode -> data = malloc((1 + strlen(str)) * sizeof(char)); 
newNode -> data = str; 

haben Sie einen String kopieren (strncpy()) str-newNode->data tun wollte?

Mit newNode->data = str; der Zeiger kopiert wird, ist der Inhalt (z. B. "wie geht es dir") nicht kopiert.

könnte eine einfache Art und Weise

sein
newNode->data = strdup(str); 

Von http://man7.org/linux/man-pages/man3/strdupa.3.html

The strdup() function returns a pointer to a new string which is a 
    duplicate of the string s. Memory for the new string is obtained 
    with malloc(3), and can be freed with free(3). 
+0

Ja, es aus irgendeinem Grunde funktioniert, könnte man erklären, warum das ändern funktioniert? – posixKing

+1

@lufork Sie setzen die Daten jedes Knotens auf denselben Wert, einen Zeiger auf 'buffer'. Somit hat jeder Knoten die gleichen Daten. –

+0

Oh danke Jungs. Aber eine kleine Frage, ich überprüfte eine andere SO-Frage und jemand erwähnte, dass strdup nicht Standard ist und daher nicht verwendet werden sollte. Wäre also im Vergleich zu straddup im Allgemeinen stärker gefördert? Danke – posixKing

1

newNode->data = str; das Problem ist. Sie sind malloc Platz für eine Zeichenfolge, die Zuordnung dieser Adresse zu newNode->data, dann sofort die Adresse zu diesem malloc Ed Speicherplatz mit der Adresse zu str, die tatsächlich die Adresse buffer den ganzen Weg von main ist. Dies schafft nicht nur ein Speicherleck, sondern erklärt auch Ihr Verhalten. Jedes Mal, wenn Sie einen Knoten erstellen, weisen Sie die Adresse newNode->data der Adresse buffer zu. Wenn also das letzte Wort "Sie" in buffer gespeichert ist, ist dies die Zeichenfolge, die alle Knoten drucken. Was Sie wirklich tun möchten, ist strcpy (oder etwas Entsprechendes) die Zeichenfolge von str in Ihrem neuen malloc ed Raum. Sie sollten auch den Rückgabewert von malloc zunächst prüfen, um sicherzustellen, dass es einen gültigen Zeiger zurückgegeben:

#include <string.h> 
.... 

if (newNode->data != NULL) 
{ 
    strcpy(newNode->data, str); 
} 
else 
{ 
    // handle error 
} 
Verwandte Themen