'I cant read a binary file with C-STYLE. Problem with strings c++ [duplicate]
For some reason, I can't read a file that contains "string"s with C-style. If I use an array of characters, then I can do it. But I want to do strings and I would like to know how to do it. When I print the b."x attribute" it shows random characters. And yes, I know I should be using c++ files. But this is purely for an educational purpose.
Code:
struct Boleta
{
string name;
string surename;
string legajo //156.455-6;
int cod_materia;
string date // 2022/10/26;
};
int main()
{
Boleta boleta;
FILE * f = fopen("DIAFINALES.DAT", "wb");
if(!f)
{
cout<<"Error al abrir el archivo 'DIAFINALES.DAT'"<<endl;
return 1;
}
while(true)
{
cout<<"Name: ", cin>>boleta.name;
cout<<"Surname: ", cin>>boleta.surename;
if(boleta.name == "NULO" && boleta.surename == "NULO")
break;
cout<<"Legajo: ", cin>>boleta.legajo;
cout<<"Exam date: ",cin>>boleta.date;
fwrite(&boleta, sizeof(boleta), 1, f);
}
fclose(f);
FILE * f1 = fopen("DIAFINALES.DAT", "rb");
if(!f1)
{
cout<<"Error al abrir el archivo 'DIAFINALES.DAT'"<<endl;
return 1;
}
Boleta b;
while(fread(&b, sizeof(b),1,f1))
{
cout<<"************************"<<b.legajo<<"******************************"<<endl;
cout<<"EXAM DATE: "<<b.date<<endl;
cout<<"Name and surname: "<<b.name<<" "<<b.surename<<endl;
cout<<"Code of subject: "<<b.cod_materia<<endl;
}
fclose(f1);
return 0;
}
Solution 1:[1]
You try to write 'boleta'
struct Boleta
{
string name;
string surename;
string legajo //156.455-6;
int cod_materia;
string date // 2022/10/26;
};
to a file like this
fwrite(&boleta, sizeof(boleta), 1, f);
this will not work. std::string is a pointer to the actual string data, the actual string is not stored in the struct.
So first you need to decide on the format of your binary file. What does each record in it look like. I suggest you have fixed size strings and the the cod_materia as 4 byte int on the end
name........surname........legajo......dat.......cod-
20 20 10(?) 10 4
To write this there are several ways
I would do
struct Bol_iobuf{
char name[20];
char surname[20];
char legato[10];
char date[10];
int cod_materia;
}
now you need to marshal a belato struct into this struct
Bolato b; // loaded with data
Bol_iobuff buff;
strcpy(buff.name,b.name.c_str());
strcpy(buff.surname,b.surname.c_str());
strcpy(buff.legato,b.lagato.c_str());
strcpy(buff.date,b.date.c_str());
buff.cod_materia= b.cod_materia;
now buff has all the bytes for one row and you can write it
fwrite(&buff, sizeof(Bol_iobuff), 1, f);
reading is the same, but in revers, read into Bol_iobuff then marshall that fields by fields into a Boleta instance
NOte that I have not checked in the marshal for write code that the strings are not too large to fit in their target char arrays (20 and 10 bytes). You could use strncpy to truncate them, or you can have guard code in your input functions to ensure you never have names too long
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
