使用列表存储.txt文件中的数据,仅存储最后一个输入(C)

时间:2014-11-16 14:30:33

标签: c list pointers visual-studio-2005 abstract-data-type

我需要一种方法来存储文件中的数据并将其保存在文件中,这一切都需要通过使用指针的列表完成,因为菜单指定它必须能够删除并搜索特定的列表中的人员数据,我的问题是,它从文件中读取数据并存储它,但是show(屏幕上)功能卡在一个循环上,显示它从最后一个人的文件中读取的数据&# 39; s信息(在指向NULL之前会在最后一个节点上发生什么),保存(到文件)功能和搜索(在列表上)和删除(从列表中)功能也会发生同样的情况,这使我认为它和#39;在某种程度上没有在列表的末尾指向NULL,我检查了几次每个功能和他们的电话并且找不到任何错误,但我几乎不是学生,我真的需要帮助,在此先感谢(如果我没有正确格式化代码,我很抱歉。)

这是我用我需要的功能创建的库:

#define EOL '\n'

struct fecha{
  int dia,mes,año;
};

struct lista{
    long cedula;
       int genero;
       char nombre[20];
       char apellido[20]; 
       char direccion[50];
       fecha f;
       lista *prox;
};

void asignar (int i,char lectura[50],lista **t){
       switch (i)
{
   case 1:
        (*t)->cedula=atol(lectura);//atol convierte string a long
       break;
   case 2:
        (*t)->genero=atoi(lectura);//atoi convierte string a int
       break;
   case 3:
        strcpy((*t)->nombre,lectura);
       break;
    case 4:
        strcpy((*t)->apellido,lectura);
        break;
    case 5:
        strcpy((*t)->direccion,lectura);
        break;
    case 6:
         (*t)->f.dia=atoi(lectura);
        break;
    case 7:
         (*t)->f.mes=atoi(lectura);
        break;
    case 8:
         (*t)->f.año=atoi(lectura);
        break;
    };
}

void insertaCab(lista **p, char path[100]){
        lista *t = new lista;//crea el nodo
        FILE *archivo;//apuntador para el archivo
        int i=1;
        char lectura[50];
        archivo = fopen(path, "r");
        if (archivo != NULL){//Si el archivo existe
            while (!feof(archivo)){//Mientras no es final de archivo
                while (i<=8){//lee 8 lineas y pasa al siguiente nodo de la lista
                 memset(lectura, 0, 50);
                  fgets(lectura,50,archivo);//Lee una linea
                   asignar(i,lectura,&t);>le pasa a asignar el contador,los datos y el apuntador de la lista
                i++;
            }i=1;
    t->prox =(*p);//T->datos->||
    (*p)=t;//P->datos->||
        }fclose(archivo);
    }
}

void muestra(lista *p){
    lista *t = p;
    while (t){
        printf("Cedula: %i\n",t->cedula);
        if (t->genero == 1) printf("Genero: Femenino\n");
        else printf("Genero: Masculino\n");
        printf("Nombre: %s\n",t->nombre);
        printf("Apellido: %s\n",t->apellido);
        printf("Direccion: %s\n",t->direccion);
        printf("Fecha de nacimiento: %i/%i/%i\n\n",t->f.dia,t->f.mes,t->f.año);

        t=t->prox;
    }
    printf("\n");
    }

int buscarlista(lista *p,long x){
lista *t=p;
while (t!= NULL ){
    if (t->cedula == x)
        return 1;
    t=t->prox;
}
return 0;
}

void eliminar(lista **p, long x){
    lista *t=(*p),*aux;
    if (t!= NULL)
        if (t->cedula == x){
            (*p)=t->prox;
            delete t;
        }
        else{
            while ((t->prox!= NULL) && (t->prox->cedula!=x))
                t=t->prox;
            if (t->prox!= NULL){
                aux=t->prox;
                t->prox=aux->prox;
                delete aux;
            }
        }
    }

void guardar(lista *p,char path[100]){
lista *t= new lista;
t=p;//apuntador auxiliar para recorrer la lista
FILE *archivo;//apuntador para el archivo
archivo = fopen(path,"a");//abre el archivo en modo append, si no existe lo crea
if(archivo !=NULL){//Si el archivo existe
 while (t){
  fprintf(archivo,"Cedula: %i\n",t->cedula);
   if (t->genero == 1) fprintf(archivo,"Genero: Femenino\n");
   else fprintf(archivo,"Genero: Masculino\n");
  fprintf(archivo,"Nombre: %s\n",t->nombre);
  fprintf(archivo,"Apellido: %s\n",t->apellido);
  fprintf(archivo,"Direccion: %s\n",t->direccion);
  fprintf(archivo,"Fecha de nacimiento: %i/%i/%i\n\n",t->f.dia,t->f.mes,t->f.año);
  t=t->prox;
    }
    fclose(archivo);
}   
}

这是我的主要内容:

void main ( )
{
 lista *p=NULL;
 long x = 0;
 int op;
 char path[100]; 
 op=-1;
 while (op!=0){
    printf ("1. Agregar\n");
    printf ("2. Buscar\n");
    printf ("3. Eliminar\n");
    printf ("4. Mostrar\n");
    printf ("5. Guardar\n");
    printf ("0. Salir\n");
    scanf ("%d", &op);
    switch (op){
        case 1: printf("Introduzca la direccion del archivo:");
                 memset(path,0,100);//Inicializa dir
                  scanf("%s",path);//Lee la direccion del archivo
                   insertaCab(&p,path);//Recibe el apuntador de la lista y la direccion del archivo
                break;
        case 2: printf("Indique el numero de cedula a buscar:");
                 scanf("%d",&x);
                  if (buscarlista(p,x) == 1)printf("El numero %i se encuentra en la lista\n",x);
                  else printf("No se encuentra en la lista\n");
                break;
        case 3: printf("Indique numero de cedula a eliminar:");
                 scanf("%d",&x);
                  eliminar(&p,x);
                break;
        case 4: muestra(p);
                break;
       case 5: printf("Introduzca la direccion en donde desea guardar la lista:");
                 memset(path,0,100);
                  scanf("%s",path);
                   guardar(p,path);
                break;
    };
 }
    }

2 个答案:

答案 0 :(得分:0)

您没有正确检测到EOF。试试这个:

void insertaCab(lista **p, char path[100]){
    char lectura[50];
    FILE *archivo; = fopen(path, "r");
    if (archivo == NULL) return;
    lista *t = new lista;
    while (fgets(lectura, 50, archivo)) {
        for (i = 1; i <= 8 && fgets(lectura, 50, archivo); i++)
           asignar(i, lectura, &t);
        if (i <= 8) break; // reached EOF before 8 lines were read.
        t->prox = *p;
        *p = t;
    }
    fclose(archivo);
}

答案 1 :(得分:0)

好吧所以我能够解决它,我错过了使用malloc函数,这就是为什么列表永远不会为NULL的原因。以下是函数的固定和工作版本,用于将数据从文件输入到列表中:

void insertaCab(lista **p, char path[100]){
    lista *t = new lista;
     t = (struct lista *) malloc( sizeof(struct lista) ); 
    char lectura[50];
    int i=1;
    FILE *archivo = fopen(path, "r");
    if (archivo == NULL) return;
        while (fgets(lectura,50,archivo)){ 
            t = (struct lista *) malloc( sizeof(struct lista) ); 
             for (i=1; (i<=8) && (fgets(lectura,50,archivo)); i++)
              asignar(i,lectura,&t);
            if(i<=8) break;
    t->prox =(*p);
    (*p)=t;
        }
        fclose(archivo);
}