Why is my vector not saved correctly in the text file?

0

The problem I have is that when I want to save the content in a text file, it does not do it, it simply saves me the garbage of the variables ... then I leave the code:

#include<stdio.h>
#include<time.h>
#include<windows.h>
struct cedula{
   int id[4],cuenta[4];
};
struct saldos{
float saldoAnterior;
};
struct banco{
cedula s;
saldos f;
};
int leer();
void llenaClientes(banco);
FILE * abrirArchivo();
void cedulaA(banco);
int main(){
int opc;
banco clientes;
do{
    printf("\nOpcion: ");
    opc=leer();
    switch(opc){
        case 1:
            llenaClientes(clientes);                
        break;  
    }   
}while(opc!=0);

}
int leer(){
int n;
scanf("%i",&n);
return n;
}


void llenaClientes(banco l){
    FILE *apuB;
    cedulaA(l);
    printf("\nIngrese el saldo del cliente: ");
    scanf("%f",&l.f.saldoAnterior);
    apuB=abrirArchivo();

    if(apuB==NULL){
        printf("\nNo se pudo abrir el archivo...");
    }else{
        fprintf(apuB,"%i|%i|%i\n",l.s.id,l.s.cuenta,l.f.saldoAnterior);
        fclose(apuB);
    }
}

FILE * abrirArchivo(){
    FILE *apufile=fopen("Banamex.txt","a+");
    return apufile;
}

void cedulaA(banco l){
    printf("\n>>>Asignando cedula y numero de cuenta<<<");
    int numero;
    int hora=time(NULL);
    srand(hora);
    for(int i=0;i<4;i++){
        l.s.id[i]=rand()%9; 
        l.s.cuenta[i]=rand()%9;
    }

}
    
asked by dan-iel 30.05.2018 в 03:38
source

2 answers

0

The problem is that you are passing banco by value:

void llenaClientes(banco l){
//                       ^ AQUI
  FILE *apuB;
  cedulaA(l);
//        ^ y aqui

Passing a variable (structure or native type) by value makes a copy of it, which will be totally independent of the original variable.

With the pointers something similar happens. The pointers are independent copies (you can make a malloc in one and the other will not know), what happens in this case is that if two or more pointers point (forgive the redundancy) to the same memory address, the changes made in the same will be shared.

The solution is to use pointers:

void llenaClientes(banco*);
void cedulaA(banco*);

int main(){
  banco clientes;
  // ...
  llenaClientes(&clientes);
  // ...
}

void llenaClientes(banco *l){
  cedulaA(l);
  // ...
  scanf("%f",&l->f.saldoAnterior);
  // ...
  fprintf(apuB,"%i|%i|%i\n",l->s.id,l->s.cuenta,l->f.saldoAnterior);
  // ...
}

void cedulaA(banco *l){
  // ...
  l->s.id[i]=rand()%9;
  l->s.cuenta[i]=rand()%9;
  // ...
}

On the other hand, note that both id as cuenta are arrays, then if to fill the structure you use an index:

for(int i=0;i<4;i++){
  l->s.id[i]=rand()%9;
  l->s.cuenta[i]=rand()%9;
}

You will need an index also to print the values:

fprintf(apuB,"%i|%i|%i\n",l->s.id,l->s.cuenta,l->f.saldoAnterior);
//                             ^^      ^^^^^^
//                             Falta el indice

Maybe something like this:

for(int i=0;i<4;i++)
{
  fprintf(apuB,"%i|%i|",l->s.id[i],l->s.cuenta[i]);
}
fprintf(apuB,"%i\n",l->f.saldoAnterior);

Although perhaps it makes more sense, instead of having two equal arrays, manage everything with a single array. Since it is understood that each identifier will correspond to an account number:

struct cedula{
  int id;
  int cuenta;
};
struct saldos{
  float saldoAnterior;
};
struct banco{
  cedula s[4];
  saldos f;
};

for(int i=0;i<4;i++){
  l->s[i].id=rand()%9;
  l->s[i].cuenta=rand()%9;
}

for(int i=0;i<4;i++)
{
  fprintf(apuB,"%i|%i|",l->s[i].id,l->s[i].cuenta);
}
fprintf(apuB,"%i\n",l->f.saldoAnterior);

Since it would allow you, for example, to use pointer arithmetic:

cedula* ptr = l->s;
for(int i=0;i<4;i++, ptr++){
  ptr->id=rand()%9;
  ptr->cuenta=rand()%9;
}

cedula* ptr = l->s;
for(int i=0;i<4;i++, ptr++)
  fprintf(apuB,"%i|%i|",ptr->id,ptr->cuenta);
    
answered by 30.05.2018 в 11:56
0

There are several problems in the code. I imagine you are using a C compiler under Windows. I have to tell you that

  • (it's an observation) The windows.h library is not necessary for what you're doing.
  • (it is an observation) The library stdlib.h is necessary for the srand (according to the standard C you have to use it).
  • The signing of the methods is not well written. It's wrong to use:

    void fullClients (bank);

  • You should use:

    void llenaClientes(struct banco);
    

    That's the standard way, the type is bank struct not just bank . You make me say what's important? Well the code that you put to not be standard will not compile with another compiler that is not yours (I had to move it because with me it just did not compile). This is what is known as portability loss.

  • (This is a critical problem) When writing to the file you are doing:

    fprintf (apuB, "% i |% i |% i \ n", l.s.id, l.s.cuenta, l.f.saldoAnterior);

  • But lsid is an arrangement the same as lscuenta so you should write each of the 4 integers of the array that represents the id and each of the 4 integers representing the account. The value of the previous balance should be printed using% f preferably indicating the decimals you are going to handle.

    fprintf(apuB,"%i%i%i%i|%i%i%i%i|%f\n"
                            ,l.s.id[0]
                            ,l.s.id[1]
                            ,l.s.id[2]
                            ,l.s.id[3]
                            ,l.s.cuenta[0]
                            ,l.s.cuenta[1]
                            ,l.s.cuenta[2]
                            ,l.s.cuenta[3]
                            ,l.f.saldoAnterior);
    
  • (This is also a critical problem). You are going through the variables of type struct bank so that when you exit the method where you pass, you lose the value they had. As @efqerion tells us, it is necessary to use indirection and pointers (pointers) at least indirectness must be used in the cedulaA () function since it initializes the values of the account and the id.
  • My proposal with the comments is:

    #include<stdio.h>
    #include<time.h>
    #include <stdlib.h> 
    
    struct cedula{
       int id[4];
       int cuenta[4];
    };
    
    struct saldos{
       float saldoAnterior;
    };
    
    struct banco{
       struct cedula s;
       struct saldos f;
    };
    
    int leer();
    void llenaClientes(struct banco);
    
    FILE * abrirArchivo();
    
    void cedulaA(struct banco * );
    
    int leer(){
        int n;
        scanf("%i",&n);
        return n;
    }
    
    
    
    int main(){
        int opc;
        struct banco clientes;
    
        do{
            printf("\nOpcion: ");
            opc=leer();
            switch(opc){
                    case 1:
                        llenaClientes(clientes);                
                    break;  
                }   
        }while(opc!=0);
    
    }
    
    
    
    
    void llenaClientes(struct banco l){
        FILE *apuB;
        // piensa esta invocación como una analogía al uso del & en
        // el scanf que haz puesto abajo.
        cedulaA(&l);
    
        printf("\nIngrese el saldo del cliente: ");
        scanf("%f",&l.f.saldoAnterior);
        apuB=abrirArchivo();
    
        if(apuB==NULL){
            printf("\nNo se pudo abrir el archivo...");
        }else{
            fprintf(apuB,"%i%i%i%i|%i%i%i%i|%f\n"
                ,l.s.id[0]
                ,l.s.id[1]
                ,l.s.id[2]
                ,l.s.id[3]
                ,l.s.cuenta[0]
                ,l.s.cuenta[1]
                ,l.s.cuenta[2]
                ,l.s.cuenta[3]
                ,l.f.saldoAnterior);
            fclose(apuB);
        }
    }
    
    FILE * abrirArchivo(){
        FILE * apufile=fopen("Banamex.txt","a+");
        return apufile;
    }
    
    void cedulaA(struct banco * l){
        printf("\n>>>Asignando cedula y numero de cuenta<<<");
        int numero;
        int hora=time(NULL);
        srand(hora);
        for(int i=0;i<4;i++){
            l->s.id[i]=rand()%9; 
            l->s.cuenta[i]=rand()%9;
        }
    
        printf("\n");
    }
    
        
    answered by 31.05.2018 в 06:46