2016-10-08 4 views
0

Ich habe versucht, ein Programm zu schreiben, das eine Zeichenfolge in den Anfang der verknüpften Liste einfügt, aber es gab ein kleines Problem darin. Mein Code ist folgender.Fehler beim Einfügen einer Zeichenfolge am Anfang einer verknüpften Liste

#include <stdio.h> 
#include <stdlib.h> 

struct node{ 
    char* data; 
    struct node* next; 
}; 



void insIni(struct node** hp, char* x){ 
    struct node* tmp = (struct node *)malloc(sizeof(struct node)); 
    tmp->data = x; 
    tmp->next = *hp; 
    *hp = tmp; 
} 

void printList(struct node* h){ 
    struct node* tmp = h; 
    printf("\nList contents: \n"); 
    while (tmp != NULL){ 
     printf("%s, ", tmp->data); 
     tmp = tmp->next; 
    } 
    printf("\n"); 
} 

int main(int argc, char const *argv[]){ 

    struct node* head = NULL; 

    char word [256]; 
    scanf("%s", word); 
    insIni(&head, word); 
    scanf("%s", word); 
    insIni(&head, word); 
    scanf("%s", word); 
    insIni(&head, word); 

    printList(head); 

    return 0; 
} 

Nachdem ich eine neue Zeichenfolge am Anfang der verknüpften Liste einfügen, werden die vorherigen Elemente auch die gleiche wie die Zeichenfolge geändert werden, die gerade insterted hat, wie kann ich den Code ändern, so dass die vorherige Elemente der verknüpften Liste bleiben gleich und nur das Element am Anfang wird hinzugefügt?

Zum Beispiel, wenn ich A B C schreibe, wird die verknüpfte Liste schließlich als C, C, C anstelle von C, B, A, gedruckt.

+0

Es funktioniert, aber 'scanf („% s“, Wort);' in main() liest den Eingang in die gleiche Zeichen-Array jedes Mal. Du könntest 'tmp-> data = x;' in isnsIni() zu 'tmp-> data = strdup (x);' – wildplasser

+0

Ok, diese Änderung schien mein Problem zu lösen, aber beim Kompilieren erhalte ich folgende Warnung: inkompatibel implizite Deklaration der eingebauten Funktion 'strdup'. Ist das gefährlich? Und wenn ja, wie kann ich es entfernen? –

+0

Sie müssen # # include 'zu verwenden strdup() (HINWEIS: strdup ist * leicht * nicht-Standard) – wildplasser

Antwort

0

Der Wert, den Sie an insIni übergeben, ist immer derselbe, so dass alle Knoten auf denselben Wert verweisen. Was Sie tun müssen, ist eine Kopie der Daten.

z.

void insIni(struct node** hp, char* x){ 
    struct node* tmp = (struct node *)malloc(sizeof(struct node)); 
    tmp->data = strdup(x); 
    tmp->next = *hp; 
    *hp = tmp; 
} 

oder

char *p = malloc(strlen(x)+1); 
strcpy(p, x); 
tmp->data = p; 
+0

Die Lösung mit strdup scheint zu arbeiten, danke! Allerdings bekomme ich beim Kompilieren eine Warnung: inkompatible implizite Deklaration der eingebauten Funktion 'strdup'. Ist das gefährlich? Und wenn ja, wie kann ich es entfernen? –

+0

@GeorgeFrancis müssen Sie die entsprechende Kopfzeile einfügen. Jede Funktion, die der C-Compiler findet, die keinen Prototyp hat, wird als int zurückgegeben. '#include ' –

+0

Danke, das schien alles zu lösen. –

0

scanf liest den Text in das Array word. Im Aufruf insIni(&head, word); übergeben Sie NICHT die Zeichenfolge, sondern die Adresse des Arrays word. In insIni in der Zeile tmp->data = x; kopieren Sie diese Adresse in die Elementdaten. Aber es ist immer noch das Array word von Funktion main. Also nächste scanf überschreibt den Inhalt dieses Arrays. Der nächste Aufruf an insIni(&head, word); wird dann der nächsten Struktur dieselbe Adresse zuweisen. Was Sie also wirklich benötigen, ist die Zuweisung von Speicher für die Zeichenfolge entweder vor (oder nach) der scanf-Anweisung oder in insIni. Etwas wie char * word; anstelle von char word [256]; und word = malloc(256); vor jedem scanf wird die Aufgabe erledigen. Auch scanf wegen Pufferüberlauf gefährlich ist, so möchten Sie wahrscheinlich diese lesen: How to prevent scanf causing a buffer overflow in C?

Verwandte Themen