Hi, I have the following code that works. The code writes or reads to a .dat file:
int main()
{
setlocale(LC_ALL, "");//para los acentos
vector<Cliente> clientes;
vector<Chofer> choferes;
bool leer=true;
if(!leer)
{
ofstream archivo("cliente.dat",ios::binary);
cout << "escribir";
if(!archivo)
{
cout << "error";
}
else
{
Cliente cli=Cliente();
cli.SetIdentificacion("11");
cli.SetApellidos("jv");
cli.SetDireccion("hbhk");
cli.SetNombre("hkbhjkb");
cli.SetTelefono("bj");
cli.SetEmail("hbjhbj");
clientes.push_back(cli);
for(Cliente c:clientes)
{
archivo.write(reinterpret_cast<const char*>(&c),
sizeof(Cliente));
}
}
}
else
{
cout <<"leer";
ifstream lectura("cliente.dat",ios::in);
while(lectura&&!lectura.eof())
{
Cliente cl=Cliente();
lectura.read(reinterpret_cast<char*>(&cl),
sizeof(Cliente));
cout << cl.GetIdentificacion() << endl;
cout << cl.GetApellidos() << endl;
cout << cl.GetEmail() << endl;
}
}
return 0;
}
So far so good, but when I want to call it from a method it returns strange characters:
void lecturaCliente()
{
ifstream lectura("cliente.dat",ios::in);
while(lectura&&!lectura.eof())
{
Cliente cl=Cliente();
lectura.read(reinterpret_cast<char*>(&cl),
sizeof(Cliente));
cout << cl.GetIdentificacion() << endl;
cout << cl.GetApellidos() << endl;
cout << cl.GetEmail() << endl;
}
}
bool escrituraCliente(vector<Cliente> clientes)
{
ofstream archivo("cliente.dat",ios::binary);
if(clientes.size()>0)
{
for(Cliente c:clientes)
{
cout << c.GetIdentificacion()<<"escr"<<endl;
archivo.write(reinterpret_cast<const char*>(&c),
sizeof(Cliente));
}
return true;
}
else
{
return false;
}
}
int main()
{
setlocale(LC_ALL, "");//para los acentos
vector<Cliente> clientes;
vector<Chofer> choferes;
bool leer=true;
if(!leer)
{
ofstream archivo("cliente.dat",ios::binary);
cout << "escribir";
if(!archivo)
{
cout << "error";
}
else
{
Cliente cli=Cliente();
cli.SetIdentificacion("11");
cli.SetApellidos("jv");
cli.SetDireccion("hbhk");
cli.SetNombre("hkbhjkb");
cli.SetTelefono("bj");
cli.SetEmail("hbjhbj");
clientes.push_back(cli);
for(Cliente c:clientes)
{
archivo.write(reinterpret_cast<const char*>(&c),
sizeof(Cliente));
}
}
}
else
{
cout <<"leer";
lecturaCliente();
}
return 0;
}
As you can see, the same code that I had in main I just passed it to a method, that's all I did. Because when I call the same code from a method it returns strange characters, like ascii characters or something like that is what it returns!!
#ifndef CLIENTE_H
#define CLIENTE_H
#include <string>
using std::string;
//Se utiliza std::string para poder hacer uso de el tipo string en la clase
class Cliente
{
public:
Cliente();
string GetIdentificacion() { return Identificacion; }
void SetIdentificacion(string val) { Identificacion = val; }
string GetNombre() { return Nombre; }
void SetNombre(string val) { Nombre = val; }
string GetApellidos() { return Apellidos; }
void SetApellidos(string val) { Apellidos = val; }
string GetDireccion() { return Direccion; }
void SetDireccion(string val) { Direccion = val; }
string GetTelefono() { return Telefono; }
void SetTelefono(string val) { Telefono = val; }
string GetEmail() { return Email; }
void SetEmail(string val) { Email = val; }
protected:
private:
string Identificacion;
string Nombre;
string Apellidos;
string Direccion;
string Telefono;
string Email;
};
#endif // CLIENTE_H
Problem.
The problem is not reading files or doing the reading in one place or another. The problem is that you don't know how the class works
std::string
, I'll explain it briefly.A
std::string
is an object that helps manage a character string, this string can change size (grow or shrink) so internally it handles dynamic memory. Let's assume that it saves two variables: a pointer and a length.In an initial state, the
std::string
will have the pointer to null and a length of zero, but if we assign a string to it, it will allocate memory for a buffer and update its pointer and length:Note that the object
std::string
is stored in a different place than the buffer in which the string is stored, so when you binary copy said object you will not be binary copying the string, you will be copying a number and a pointer; that pointer will only make sense in the context, scope and execution in which the objectstd::string
that handles it was created, outside of those conditions the pointer will point to memory that was not reserved or filled with consistent data, so you get strange characters .One moment! So why does it work sometimes? I will not go to the extreme of stating that it is not possible, even if it is signed by Bjarne Stroustrup 1 himself with his own blood on a piece of his own skin, since there is a chain of coincidences that can give rise to that it could be possible that it could come to pass what you observe; you can intuit it by reading this answer .
Solution.
To save and read text strings in and from files, you will have to save their length and content separately, I advise you to do it in separate functions:
With these functions and following modern C++ practices your code could look something like:
1
.