2017-04-02 156 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

是的,这就是为什么使用'一般'的原因,但是使用虚拟节点来掩盖分配常常会留下一个重要部分的学习,以便充分理解操纵列表中的第一个节点。这就是为什么我没有更多地将它作为评论放弃。 –