2017-01-31 2 views
1

Also versuche ich, einen Stapel von Strings in C zu erstellen, und ich stehe auf ein Problem. Das Ziel besteht darin, eine Datei zu lesen und umgekehrt zu drucken. Ich entschied, dass ein Stack der geeignetste Weg wäre, dies zu tun (ich weiß, es gibt einfachere Möglichkeiten, dies zu tun, aber ich wollte mich selbst mit der Verwendung von Strukturen herausfordern).C Probleme mit einem Strings-String

Hier ist mein Push/Print Code:

void push(struct LineStack * stack, char * line) 
{ 
    if(!stack->head) 
    { 
     stack->head = malloc(sizeof(struct entry *)); 
     stack->head->data = line; 
     stack->head->next = NULL; 
     stack->top = stack->head->data; 
     stack->size++; 
    } 
    else 
    { 
     struct entry * entry = malloc(sizeof(struct entry *)); 
     entry->data = line; 
     entry->next = stack->head; 
     stack->head = entry; 
     stack->top = stack->head->data; 
     stack->size++; 
    } 
}                             

void printStack(struct LineStack * stack) 
{ 
    while(stack->head) 
    { 
     printf("%s\n", stack->head->data); 
     stack->head = stack->head->next; 
    } 
} 

Und hier ist main/tempFile.txt:

int main(void) 
{ 
    struct LineStack * stack = newStack(); 
    char * fileName = "tempFile.txt" 
    char line[SIZE]; 

    FILE * fp = fopen(fileName, "r"); 

    while(fgets(line, 128, fp) != NULL) 
     push(stack, line); 

    printStack(stack); 

    free(stack); 

    return 0; 
} 

tempFile.txt:

Lets begin 
We'll say 2 + 2 = 4 
But then go ahead and prove that 1 + 2 + 3 + 4 + ... = -1/12 
How can this be? 
How can this be? 

Wenn ich versuche, Führe den Code aus, druckt die korrekte Anzahl von Zeilen in der Datei aus (5), druckt aber nur "Wie kann das sein". Jetzt habe ich versucht, mit GDB zu sehen, was das Problem ist, und es scheint, dass die Push-Anrufe ordnungsgemäß funktionieren. Bei jedem Aufruf wird eine andere Zeile an einem anderen Speicherort abgelegt, sodass ich annehmen muss, dass die Verknüpfungsliste, die den Stapel ausmacht, einwandfrei funktioniert. Fehle ich etwas dumm und klein?

Als Referenz ist hier die Eingabe/LineStack Erklärungen:

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

struct LineStack 
{ 
    struct entry * head; 
    char * top; 
    int size; 
}; 

Vielen Dank im Voraus.

+0

wo ist 'newStack()'? –

+0

newStack() und SIZE sind nicht definiert – BlueCollar

+1

Sie sollten die meisten, wenn nicht alle Spezialcode-Duplizierung in der 'push()' -Funktion vermeiden. –

Antwort

0

Ihre main() liest jede Zeile in das lokale Array line. Es übergibt dann (ein Zeiger auf) dieses Array an Funktion push(). Diese Funktion speichert diesen Zeiger einfach im Stapel - die Daten werden nicht kopiert, nur der Zeiger. Daher enthalten alle Stapeleinträge Zeiger auf dasselbe Array. Wenn Sie sie drucken, enthält dieses Array die letzte Zeile, die aus der Datei gelesen wird, und das ist, was Sie drucken, so oft Sie Zeilen lesen.

Sie müssen die Eingabezeichenfolgen kopieren. Wenn Sie strdup() haben (eine POSIX-Funktion, aber keine Standard-C-Datei), dann ist das der einfachste Weg, eine solche Kopie zu erstellen. Andernfalls wäre [strlen() +] malloc() + strcpy() der herkömmliche Weg, um Kopien Ihrer Strings zu erstellen. Wie auch immer, denken Sie daran, dass Sie dafür verantwortlich sind, jedes Stück dynamisch zugewiesenen Speicher freizugeben, wenn Sie damit fertig sind, bevor Sie zulassen, dass der letzte Zeiger darauf verloren geht.

+0

Danke schön :). Das hat perfekt funktioniert. –

0

Abgesehen von dem, was @JohnBollinger schon gesagt, Sie haben folgendes Problem:

stack->head = malloc(sizeof(struct entry *)); 

Hier ordnen Sie einen Teil des Speichers von der Größe eines Zeiger zu struct entry, nicht die Größe struct entry selbst. Es sollte sein:

stack->head = malloc(sizeof(struct entry)); 

Das gleiche Problem tritt auf, wenn Sie Speicher für ein stack->entry zuordnen.