2016-07-27 21 views
0

Ich versuche ein Programm zu schreiben, das Daten aus einer Excel-Datei importiert und Namen in einer verknüpften Liste speichert. Die erste Spalte enthält einen Befehl {add, remove, flush}, und die zweite Spalte enthält einen Namen, wenn if der Befehl add ist.C89 Löschen von verknüpften Listen

Es fügt Namen am Ende der Liste hinzu, entfernt Namen von vorne und löscht beim Löschen die gesamte Liste aus dem Speicher. Add erkennt, ob der Name bereits enthalten ist (noch nicht in geschrieben) Flush und entfernen Sie auch erkennen, ob die Warteschlange leer ist.

Beispieldatei:

add  dave 

add  mike 

remove 

add  paul 

flush 

add  steve 

Beispiel Ausgabe:

add:  dave 

add:  dave, mike 

remove: mike 

flushing queue 

add:  steve 

Mein Problem ist, dass mein Flush-Befehl richtig die Liste nicht löschen. Der Code muss c89-konform sein. Danke für jede Hilfe, die Sie geben können.

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

struct node { 
struct node* next; 
char name[50]; 
}; 

struct node* addNode(char *word); 
void freeNodes(struct node* head); 
void removeNode (struct node* head); 

int main(void) 
{ 
struct node* head = NULL, *tail, *temp; 
char buffer[50]; 
int i; 
char *word = " "; 
char *del = " ,\n"; 
FILE *fp; 

fp = fopen("queue-data.csv", "r"); 

while(fgets(buffer, sizeof(buffer), fp) != NULL) 
{ 
    word = strtok(buffer, del); 

    /********  ADD  *********/ 

    if(strcmp(word,"add") == 0) 
    { 
     word = strtok(NULL, del); 
     temp = addNode(word); 
     if(head == NULL) 
      head = temp; 
     else 
      tail->next = temp; 

     tail = temp; 
     temp = head; 

     printf(" add:"); 
     printf(" %s", temp->name); 
     temp = temp->next; 

     while(temp != NULL) 
     { 
      printf(", %s", temp->name); 
      temp = temp->next; 
     } 
     printf("\n"); 
    } 

    /********  REMOVE  *********/ 

    else if(strcmp(word,"remove") == 0) 
    { 
     printf("remove:"); 
     if (head == NULL) 
      printf(" queue is empty"); 
     else 
     { 
      removeNode(head); 
     } 
     printf("\n"); 
    } 


    /********  FLUSH  *********/ 


    else if(strcmp(word,"flush") == 0) 
    { 
     if (head == NULL) 
      printf(" flush: queue is empty"); 
     else 
      freeNodes(head); 
     printf("\n"); 
    } 

} 
freeNodes(head); 
} 


struct node* addNode(char *word) 
{ 
struct node* temp = malloc(sizeof(struct node)); 
strcpy(temp->name, word); 
temp->next = NULL; 

return temp; 
} 

void freeNodes(struct node* head) 
{ 
struct node* temp; 

printf(" flushing queue"); 
while(head != NULL) 
{ 
    temp = head->next; 
    free(head); 
    head = temp; 
} 
} 

void removeNode (struct node* head) 
{ 
struct node* temp; 

temp = head->next; 
free(head); 
head = temp; 
printf(" %s", temp->name); 
temp = temp->next; 
while(temp != NULL) 
{ 
    printf(", %s", temp->name); 
    temp = temp->next; 
} 
} 
+0

Nur ein Kommentar: C ist die bestmögliche Sprache für die Leistung und verkettete Listen sind die schlechteste mögliche Datenstruktur für die Leistung wegen Cache-Lokalität. Warum möchten Sie eine Sprache verwenden, die schwer zu benutzen ist und dann ihren primären Anwendungsfall absichtlich vereitelt? Wenn Sie sich nicht um die Leistung kümmern, verwenden Sie die VBA von Excel. –

+0

Können Sie bitte definieren, dass die Liste nicht ordnungsgemäß gelöscht wird? Schließt das Programm einfach, ohne etwas zu löschen oder löscht es etwas oder stürzt es einfach ab? –

Antwort

0

Das Problem ist Ihre removeNode() Funktion.
Es ändert die Adresse des Zeigerkopfes - was lokal in removeNode() ist - und freien Speicher des Knoten es Zeiger vor, während der Zeiger Kopf in Hauptfunktion nicht ändern. Also, wenn Sie removeNode(head) aufrufen, Zeiger Zeiger in Haupt noch auf Speicher zeigen, wo in removeNode() Funktion freigegeben werden, so ging es falsche Befehle nach.
Dies sind einige Lösung:

  • Zeigerkopf definieren globale Variable
  • Funktion removeNode() sollte der Kopfzeiger nach der Rück geändert werden. wie folgt:
    struct node* removeNode(struct node* head){}

Sag mir, wenn es hilft.

Verwandte Themen