0

I want to save the following struct into a binary file:

struct Usuario{
    char nombre[256];
    char apellido[256];
    char ingresos[256];
    std::vector<Bill> manejador_facturas;

};

Bill is also a struct:

struct Bill{
    float monto;
    int dia;
    int mes;
    int anio;
    char empresa[256];
};

What I tried to write the information into the binary file was:

void Perfil::GuardarEnBinario(std::ostream &archivo) {
    Usuario reg;
    Bill auxiliar;

    strcpy(reg.nombre, nombre.c_str());
    strcpy(reg.apellido, apellido.c_str());
    strcpy(reg.ingresos, ingresos.c_str());

    for(size_t i = 0; i < manejador_facturas.size(); i++){
        strcpy(auxiliar.empresa, manejador_facturas[i].empresa);
        auxiliar.monto = manejador_facturas[i].monto;
        auxiliar.dia = manejador_facturas[i].dia;
        auxiliar.mes = manejador_facturas[i].mes;
        auxiliar.anio = manejador_facturas[i].anio;
        reg.manejador_facturas.push_back(auxiliar);
    }
    archivo.write((char*)&reg, sizeof(reg));
}

At first I thought it worked because the .exe worked fine, but the problem is that the information that I saved, wasn't showing at all when I tried to see it (don't know if the .bin was corrupted or what). The code for reading the struct is:

void Perfil::LeerDesdeBinario(std::istream &archivo) {
    Usuario reg;
    Bill auxiliar;
    archivo.read((char*)&reg, sizeof(reg));
    nombre = reg.nombre;
    apellido = reg.apellido;
    ingresos = reg.ingresos;

    for(size_t i = 0; i < reg.manejador_facturas.size(); i++){
        strcpy(auxiliar.empresa, reg.manejador_facturas[i].empresa);
        auxiliar.monto = reg.manejador_facturas[i].monto;
        auxiliar.dia = reg.manejador_facturas[i].dia;
        auxiliar.mes = reg.manejador_facturas[i].mes;
        auxiliar.anio = reg.manejador_facturas[i].anio;
        manejador_facturas.push_back(auxiliar);
    }
}
2
  • archivo.read((char*)&reg, sizeof(reg)); once you have the vector or any other non pod type in the structure this method of reading and writing the structure is no longer an option. Commented Feb 2, 2020 at 23:13
  • @drescherjm Didn't know that... Can you suggest something on how can I read/write? Commented Feb 2, 2020 at 23:22

1 Answer 1

1

Welcome to Stack Overflow. Writing and reading complex structures is simply not that easy. (And you ought to have attempted simpler types before advancing to this one.)

Let us start with a char[256]:

void GuardarEnBinario(char *A, std::ostream &archivo)
{
  ofstream fout("data", ios::out | ios::binary);
  archivo.write(A, 256);
}

void LeerDesdeBinario(char *B, std::istream &archivo)
{
  archivo.read(B, 256);
}

Test this before you proceed.

Now try a Bill:

void GuardarEnBinario(Bill &B, std::ostream &archivo)
{
  archivo.write((char*)&B.monto, sizeof(float));
  archivo.write((char*)&B.dia, sizeof(int));
  GuardarEnBinario(B.empresa, archivo);
}

void LeerDesdeBinario(Bill &B, std::istream &archivo)
{
  archivo.read((char*)&B.monto, sizeof(float));
  archivo.read((char*)&B.dia, sizeof(int));
  LeerDesdeBinario(B.empresa, archivo);
}

(I have omitted some of the fields; it should be clear how to handle them.)

Test this, and be sure that you understand it, before you proceed.

Now try a vector<Bill>:

void GuardarEnBinario(std::vector<Bill> &V, std::ostream &archivo)
{
  unsigned int n = V.size();
  cout << n << endl;
  archivo.write((char *) &n, sizeof(unsigned int));
  for(unsigned int k=0; k<n; ++k)
    {
      GuardarEnBinario(V[k], archivo);
    }
}

void LeerDesdeBinario(std::vector<Bill> &V, std::istream &archivo)
{
  unsigned int n;
  archivo.read((char *) &n, sizeof(unsigned int));
  cout << n << endl;
  Bill B;
  for(unsigned int k=0; k<n; ++k)
    {
      LeerDesdeBinario(B, archivo);
      V.push_back(B);
    }
  }

Once you have this working, the rest of your task should be easy.

Sign up to request clarification or add additional context in comments.

11 Comments

I forgot to include in the question that my vector<Bill> is already included in the private part of the class that has this metod. So, I don't understand why do I have to "send" again to the metod you told me the vector. Besides, GuardarEnBinario is called by another metod in other header that only asks for a string, that way it can creat the binary file. That's why GuardarEnBinario only recieves the file. I don't know if I am explaining myself. Please, let me know if you need more information.
@AugustoGiavedoni: I understand, and we can solve these problems after we have the basic code working. Have you tried the code I posted? Do you understand it? Do you have it working? Festina lente.
I understand your code, but not the part where you use the vector because I can't see how can I use it with my program. That's why I told you that I don't send the vector to the metod, etc. etc.
@AugustoGiavedoni: Good! Now if GuardarEnBinario is to be a member of Usuario, then there is no need for a vector<Bill> argument; you can use manejador_facturas instead of V. And if GuardarEnBinario is a public method, then code outside of its class can call it.
Yes, we agree in that! Now, you told before that I need to do this: for(unsigned int k=0; k<n; ++k) { GuardarEnBinario(V[k], archivo); } How can I edit that if I'm not sending a vector<Bill> argument? Because I don't have a way to iterate the actual vector, in this case manejador_facturas.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.