0

I have this code to print the content of a .txt file that includes the description, code-name, date and price of an unknown number of products (this is because it is supposed to work with any .txt file). The problem is that my program only prints the last product of the .txt file. I don't know why that happens. Thanks in advance!

This is the program:

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

This is the .txt file:

Pizza

124g284j2

10/02/19

230.93

Hamburger

27842yh28

23/09/23

197.00

Carrot

283u1j23

31/12/17

89.98

Ice Cream

3613y23u2

12/11/34

234.98

Community
  • 1
  • 1
Thomas GM
  • 27
  • 10

1 Answers1

0

In your C++ program, you have to put the node allocations inside the while loop. fgets(desc, LDES, pf) should also be inside the while loop.

Your filename probably has *.cpp extention, you are compiling in C++. You have to change the file extenstion to *.c, or you can set the compiler option to use C compiler.

The correct declaration in C is:

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

You can put fgets call sequentially as they appear in input file. Use fscanf(pf, "%f\n"... to read the last character. Example:

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

You can also add error check for fscanf. If fscanf is successful, it will return the number of items it reads. Example

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

You have unnecessary allocation for node for in mostrarLista. It allocates memory for actual, but in the next line actual is set primero Now you have a memory leak, there is no way to free memory from malloc. You simply need

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;
    }
}
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77