我的简单列表仅打印.txt文件的最后一个元素

时间:2017-11-05 23:39:36

标签: c list

我有这个代码来打印.txt文件的内容,其中包含未知数量产品的描述,代码名称,日期和价格(这是因为它应该适用于任何.txt文件)。 问题是我的程序只打印.txt文件的最后一个产品。我不知道为什么会这样。提前谢谢!

这是该计划:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define LDES 32
#define LCOD 16

struct fecha { int d, m, a; };
struct ventas {
  char descripcion[LDES];
  char codigo[LCOD];
  struct fecha ultRep;
  float venta;
};
struct nodo {
  struct ventas d;
  struct nodo *sig;
};
nodo*primero = NULL;
nodo*ultimo = NULL;

void leerTexto(void) {
  nodo*nuevo = (nodo*)malloc(sizeof(nodo));
  char desc[LDES];
  char cod[LCOD];
  FILE *pf = fopen("ventas.txt", "r");
  if (pf) {
    fgets(desc, LDES, pf);
    while (!feof(pf)) {
        strcpy(nuevo->d.descripcion, desc);
        fgets(cod, LCOD, pf);
        strcpy(nuevo->d.codigo, cod);
        fscanf(pf, "%d/%d/%d", &nuevo->d.ultRep.d, &nuevo->d.ultRep.m, &nuevo->d.ultRep.a);
        fgetc(pf);
        fscanf(pf, "%f", &nuevo->d.venta);
        fgetc(pf);
        if (primero == NULL) {
            primero = nuevo;
            primero->sig = NULL;
            ultimo = nuevo;
        }
        else {
            ultimo->sig = nuevo;
            nuevo->sig = NULL;
            ultimo = nuevo;
        }
        fgets(desc, LDES, pf);
    }
    fclose(pf);
  }
}

void mostrarLista(void) {
  nodo* actual = (nodo*)malloc(sizeof(ventas));
  actual = primero;
  if (primero != NULL) {
    while (actual != NULL) {
      printf("%s\n", actual->d.descripcion);
      printf("%s\n", actual->d.codigo);
      printf("%d/%d/%d\n", actual->d.ultRep.d, actual->d.ultRep.m, actual->d.ultRep.a);
      printf("%f\n", actual->d.venta);
      actual = actual->sig;
    }
  }
}

int main(void) {
  leerTexto();
  mostrarLista();
  return 0;
}

这是.txt文件:

  

披萨

     

124g284j2

     

19年10月2日

     

230.93

     

汉堡包

     

27842yh28

     

23/09/23

     

197.00

     

胡萝卜

     

283u1j23

     

31/12/17

     

89.98

     

冰淇淋

     

3613y23u2

     

34年12月11日

     

234.98

1 个答案:

答案 0 :(得分:0)

在C ++程序中,必须将节点分配放在while循环中。 fgets(desc, LDES, pf)也应位于while循环内。

您的文件名可能有* .cpp扩展名,您正在使用C ++进行编译。您必须将文件扩展名更改为* .c,或者您可以将编译器选项设置为使用C编译器。

C中的正确声明是:

struct nodo* nuevo = malloc(sizeof(struct nodo));

您可以按顺序将fgets调用放入输入文件中。使用fscanf(pf, "%f\n"...读取最后一个字符。例如:

if(pf) 
{
    while(fgets(desc, LDES, pf)) 
    {
        struct nodo* nuevo = malloc(sizeof(struct nodo));
        strcpy(nuevo->d.descripcion, desc);
        fgets(nuevo->d.codigo, LCOD, pf);
        fscanf(pf, "%d/%d/%d\n", 
            &nuevo->d.ultRep.d, &nuevo->d.ultRep.m, &nuevo->d.ultRep.a);
        fscanf(pf, "%f\n", &nuevo->d.venta);
        if(primero == NULL) 
        {
            primero = nuevo;
            primero->sig = NULL;
            ultimo = nuevo;
        }
        else 
        {
            ultimo->sig = nuevo;
            nuevo->sig = NULL;
            ultimo = nuevo;
        }
    }
    fclose(pf);
}

您还可以为fscanf添加错误检查。如果fscanf成功,它将返回它读取的项目数。实施例

if(3 != fscanf(pf, "%d/%d/%d\n",
    &temp.ultRep.d, &temp.ultRep.m, &temp.ultRep.a))
        break;

您在node中为mostrarLista分配了不必要的内容。它为actual分配内存,但是在下一行actual设置primero现在你有内存泄漏,没有办法从malloc释放内存。你只需要

void mostrarLista(void) 
{
    struct nodo* actual = primero;
    while(actual != NULL) 
    {
        printf("%s", actual->d.descripcion);
        printf("%s", actual->d.codigo);
        printf("%d/%d/%d\n", actual->d.ultRep.d, actual->d.ultRep.m, actual->d.ultRep.a);
        printf("%f\n\n", actual->d.venta);
        actual = actual->sig;
    }
}