2017-04-02 3 views
0

Ich versuche Elemente einer Datei in eine verkettete Liste einzufügen, ich habe zwei Funktionen verwendet, eine, die lädt und die Einfügungen, die Funktion lädt läuft anscheinend in der richtigen Weise, aber die Funktion einfügen startet die Implementierung und endet nicht, beim Testen habe ich festgestellt, dass sie es schafft, die ersten 3 Zeilen der Datei eingeben, aber die Einfügung nicht korrekt abgeschlossen, da der Code lang ist, folgt, dass ein Teil davon Probleme:Verknüpfte Liste - Einfügen

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#define RECS_PATIO 2 

struct Rec_Emp { 
    char nome_rec[10]; 
    int uso_rec; 
    int taxa_rec; 
/* struct Rec_Emp *prox; */ 
}; 

typedef struct Rec_Emp recuperadora; 

struct Patio { 
    char iden_patio; 
    int capacidade; 
    struct Patio *prox; 
    struct Rec_Emp *lista[RECS_PATIO]; 
}; 

typedef struct Patio patio; 

void insere_patio (patio *cabeca, patio *novo) { 
    patio *p = cabeca; 

    while (p->prox != NULL) 
     p = p->prox; 
    novo->prox = p->prox; 
    p->prox = novo; 

} 

void carrega_patio (patio *pa, patio p, recuperadora r1, recuperadora r2) { 
    patio *pt = pa; 
    FILE *f; 

    f = fopen ("portorec.txt", "rt"); 

    if (f == NULL) { 
     printf ("Problema na abertura do arquivo"); 
     return; 
    } 

    while (!feof(f)) { 
     fscanf (f, "%d %c %s %s %d %d %d %d", &p.capacidade, &p.iden_patio, r1.nome_rec, r2.nome_rec, &r1.uso_rec, &r2.uso_rec, &r1.taxa_rec, &r2.taxa_rec); 

     p.lista[0] = &r1; 
     p.lista[1] = &r2; 
     insere_patio(pt, &p); 

    } 
    fclose(f); 
} 

int main { 

patio *PT; 
    PT = malloc(sizeof(patio)); 
    PT->prox = NULL; 
    patio pat; 
    recuperadora rec1, rec2;  
    carrega_patio(PT, pat, rec1, rec2); 
} 

Datei

600000 A REC01 - 0 -1 6000 -1 
600000 B REC01 REC03 0 0 6000 8000 
600000 C REC02 REC03 0 0 6000 8000 
600000 D REC02 - 0 -1 6000 -1 
2400000 E ER01 ER02 0 0 8000 8000 
2400000 F REC04 ER01 0 0 8000 8000 
2400000 G REC04 - 0 -1 8000 -1 
2400000 H REC05 - 0 -1 8000 -1 
2400000 I REC05 - 0 -1 8000 -1 
2400000 J ER02 - 0 -1 8000 -1 

Antwort

0

In main deklarieren Sie patio pat als eine automatische Variable (auf dem Stapel zugeordnet). Automatische Variablen werden standardmäßig nicht initialisiert. Sie erhalten also den zufälligen Müll, der zufällig im Stapel liegt, als Wert für pat.prox. Ich erwarte, dass Ihre Listeneinfügung zufällige Müllzeiger im gesamten Speicher sucht und nach p->prox == NULL sucht.

Darüber hinaus reservieren Sie Ihren Speicher nicht dynamisch in carrega_patio. Die Parameter patio p, recuperadora r1, recuperadora r2 sind alle Strukturen, aber diese Strukturen werden wiederverwendet jedes Mal durch Ihre Schleife.

Stellen Sie sich vor, Sie füllen ein Papierformular mit 1 Zeile dieser Daten aus. Und dann ausgehend von der Spitze des gleichen Papierformulars und füllen Sie genau die gleiche Form mit einer anderen Zeile dieser Daten. Und dann wieder und wieder.

Da Sie Speicher nicht separat zuweisen, können Sie keine Liste erstellen. Sie müssen malloc() oder calloc() anrufen, um für jeden Datensatz ein "neues Stück Papier" zuzuweisen.

Probieren Sie etwas wie diese (Anmerkung: nicht getestet): #include #include

typedef const char * FILESPEC; 

typedef struct rec_emp { 
    #define RE_NOME_DIM 10 

    int  re_taxa; 
    int  re_uso; 
    char  re_nome[RE_NOME_DIM]; 
} REC_EMP; 

typedef struct patio { 
    #define PA_LISTA_DIM 2 

    struct patio *pa_prox; 
    int  pa_capacidade; 
    char pa_iden; 
    REC_EMP pa_lista[PA_LISTA_DIM]; /* NOTE: structs, NOT pointers */ 

    #define pare(pa,n) ((pa)->pa_lista[(n)]) 
} PATIO; 

PATIO * 
patio_novinho() 
{ 
    PATIO * p = calloc(1, sizeof (PATIO)); 
    return p; 
} 

void 
patio_insere(cabeca, novo) 
    PATIO * cabeca; 
    PATIO * novo; 
{ 
    while (cabeca->pa_prox) { 
     cabeca = cabeca->pa_prox; 
    } 
    novo->pa_prox = cabeca->pa_prox; 
    cabeca->pa_prox = novo; 
} 

void 
patio_carrega(cabeca, arquivo) 
    PATIO * cabeca; 
    FILESPEC arquivo; 
{ 
    FILE *fp = fopen(arquivo, "rt"); 

    if (fp == NULL) { 
     perror("patio_carrega: Problema na abertura do arquivo"); 
     exit(1); 
    } 

    while (!feof(fp) && !ferror(fp)) { 

     PATIO * pa = patio_novinho(); 

     fscanf(fp, "%d %c %s %s %d %d %d %d", 
      &pa->pa_capacidade, 
      &pa->pa_iden, 
      pare(pa,0).re_nome, 
      pare(pa,1).re_nome, 
      &(pare(pa,0).re_uso), 
      &(pare(pa,1).re_uso), 
      &(pare(pa,0).re_taxa), 
      &(pare(pa,1).re_taxa) 
     ); 

     patio_insere(cabeca, pa); 

    } 

    fclose(fp); 
} 

int 
main() 
{ 
    PATIO * cabeca = patio_novinho(); 
    patio_carrega(cabeca, "portorec.txt"); 

    /* more stuff here */ 
    exit(0); 
} 
+0

On-Einsatz, sind Sie in der Regel erforderlich, um die * Adresse * die Liste als Parameter zu übergeben, da, wenn der Speicher Wird für den Knoten reserviert und als Kopf (die Adresse der Liste) zugewiesen, müssen Sie auf den eigentlichen Zeiger selbst und nicht auf eine Kopie handeln. Aus diesem Grund muss die Einfügung mindestens zwei Bedingungen überprüfen: (1) ob dies der erste Knoten in der Liste ist; und (2) falls nicht, iteriere zum nächsten freien Knoten zum Einfügen. –

+0

Ich denke, das OP arbeitet daran, indem es immer einen Dummy-Knoten am Anfang der Liste verwendet. Trading-Heap für Code, sozusagen. –

+1

Ja, deshalb wurde das 'allgemein' verwendet, aber die Verwendung eines Dummy-Knotens zum Maskieren der Zuweisung lässt oft einen wichtigen Teil des Lernens aus, der notwendig ist, um das Manipulieren des ersten Knotens in einer Liste vollständig zu verstehen. Deshalb habe ich es als Kommentar weggelassen. –