Stacks a file in C

0

I have thought to pass the data from a stack to a binary file, I have done a few steps but I think they are wrong, I see the last element element introduced, I mean the first one in the stack.

Code:

typedef struct nodo
{
    int dato;
    struct nodo *siguiente;
}Nodo;

Nodo *principioPila = NULL;

//Prototipos de funciones
void escribirFichero(void);
int introducirDatos(void);
void leerFichero(void);

int main()
{
    printf("PILA A UN FICHERO BINARIO\n\n");
    escribirFichero();
    system("CLS");
    printf("DATOS DE LA PILA GUARDADOS EN EL FICHERO\n\n");
    printf("NUMEROS\n");
    leerFichero();

    return 0;
}

void escribirFichero(void)
{
    FILE *fichero = fopen("pila.dat","wb");

    if(fichero == NULL)
    {
        printf("Error en el fichero");
    }
    else
    {   
        Nodo *nuevo;
        int numero = introducirDatos();

        while(numero!=0)
        {
            nuevo = (Nodo*)malloc(sizeof(Nodo));
            nuevo->dato = numero;
            nuevo->siguiente = principioPila;
            principioPila = nuevo;
            numero = introducirDatos();
        }
        fwrite(&principioPila,sizeof(principioPila),1,fichero);     
    }
    fclose(fichero);
}

int introducirDatos(void)
{
    int x;
    printf("Dato: ");
    scanf("%d",&x);
    return x;
}

void leerFichero(void)
{
    FILE *fichero = fopen("pila.dat","rb");

    if(fichero == NULL)
    {
        printf("Error en el fichero");
    }
    else
    {
        fread(&principioPila,sizeof(principioPila),1,fichero);
        while(!feof(fichero))
        {
            printf(" %d",principioPila->dato);
            principioPila = principioPila->siguiente;
            fread(&principioPila,sizeof(principioPila),1,fichero);  
        }   
    }
    fclose(fichero);
}
    
asked by Mario Guiber 04.09.2017 в 22:14
source

1 answer

2

The program works with chiripa. If you did two independent programs, one to write the file and another to read it would never work.

Let's start:

while(numero!=0)
{
    nuevo = (Nodo*)malloc(sizeof(Nodo));
    nuevo->dato = numero;
    nuevo->siguiente = principioPila;
    principioPila = nuevo;
    numero = introducirDatos();
}
fwrite(&principioPila,sizeof(principioPila),1,fichero);     

This fragment has two important errors:

  • You only keep one record, regardless of the number of items on the stack (this makes it impossible for you to retrieve more than one value)
  • In the file it is saving memory addresses, not the value of the elements.
  • Let's go in parts:

    You only save a record

    Indeed, your algorithm only has a fwrite and is also out of any loop, then you will hardly be able to dump the entire stack in the file.

    You need to iterate over the stack in order to save all the data:

    Nodo* ptr = principioPila;
    while( ptr )
    {
      fwrite(/* ... */); // Lo vemos más adelante
      ptr = ptr->siguiente;
    }
    

    Save memory addresses

    With &principioPila you will recover the memory address where the pointer is located ... and that is what you are storing in the file. You need to store the value of the node in question. The program is working because, by not releasing memory, memory addresses are valid between reading and writing.

    The writing instruction should look like this:

    fwrite(&(principioPila->dato),sizeof(int),1,fichero);
    //     ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^
    //               (1)              (2)
    

    And the explanation is as follows:

  • The only data that makes sense in each node is the field dato . The other value stored in the node is a memory address ... and this data will change between executions, then it does not make sense to store it.

  • Since you are only going to store an integer you have to guarantee that the program only writes the number of bytes occupied by an integer.

  • to finish writing

    With the previous changes you have already saved the stack in the file ... the next step should be to free the memory from the stack. This step I leave to you since you have not even tried to touch it.

    ... and now let's review the reading:

    fread(&principioPila,sizeof(principioPila),1,fichero);
    while(!feof(fichero))
    {
        printf(" %d",principioPila->dato);
        principioPila = principioPila->siguiente;
        fread(&principioPila,sizeof(principioPila),1,fichero);  
    }   
    

    Unlike writing, here if you have a fread within the loop, then in principle the program will be able to read several records ... but you're trying to recover memory addresses ... bad stuff.

    According to what we have seen in the writing, the reading should be like this:

    int dato;
    fread(&dato,sizeof(int),1,fichero);
    
    nuevo = (Nodo*)malloc(sizeof(Nodo));
    nuevo->dato = dato;
    nuevo->siguiente = principioPila;
    // ...
    

    That is, you have to rebuild the stack. It is expected when you read a file ... you do not know what you will find in it, then you have to reconstruct your lists on the fly.

        
    answered by 04.09.2017 / 22:37
    source