2017-04-02 211 views
0

我試圖插入鏈接列表中的文件的元素,我使用了兩個函數,一個加載和哪個插入,函數加載正在運行,顯然,以正確的方式,但是函數insert正在啓動實施,並沒有結束,測試我注意到她設法輸入文件的前3行,但沒有正確完成插入,因爲代碼很長,所以它的部分問題如下:鏈接列表 - 插入

#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); 
} 

文件

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 

回答

0

main,您聲明patio pat作爲自動變量(分配在堆棧上)。自動變量默認情況下不會被初始化,所以你會得到任何隨機垃圾恰好在棧上的值爲pat.prox。我期望你的列表插入在內存中追蹤隨機垃圾指針,尋找p->prox == NULL

此外,你不動態分配你的內存在carrega_patio。參數patio p, recuperadora r1, recuperadora r2都是結構,但這些結構將在每次循環中重複使用

想象一下,用這行數據填寫一份紙質表格。然後從相同紙質表格的頂部開始,填寫完全相同的表格,並用不同的這一行數據。然後再一次,再一次。

由於您沒有單獨分配內存,因此無法創建列表。您需要撥打malloc()calloc()爲每條記錄分配一張「新紙」。

嘗試是這樣的(注:未測試): 的#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

在插入,你通常需要通過的*列表中*地址作爲參數,因爲當內存分配給節點並作爲頭部(列表的地址)分配,則必須根據實際指針而不是副本進行操作。這就是爲什麼插入必須至少檢查兩個條件,(1)這是否是列表中的第一個節點;和(2)如果不是迭代到下一個空閒節點插入。 –

+0

我認爲OP通過在列表前面始終使用「虛擬」節點來解決這個問題。交易堆代碼,就像它。 –

+1

是的,這就是爲什麼使用'一般'的原因,但是使用虛擬節點來掩蓋分配常常會留下一個重要部分的學習,以便充分理解操縱列表中的第一個節點。這就是爲什麼我沒有更多地將它作爲評論放棄。 –