Problem reading from file
Oct 30, 2014 at 4:21pm UTC
Hello everyone, i have this code, but when i tried to read from the file, it crash.
this is my code. When im using nombre as char, it works, but when string it doesnt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
#include<fstream>
#include <iostream>
using namespace std;
struct {
int matricula;
string nombre;
int edad;
}alumno;
int main() {
int opc;
do {
cout <<endl << "1. Capturar" <<endl;
cout << "2. Mostrar" ;
cin >>opc;
if (opc==1){
cout <<"dame matricula :" ;
cin >> alumno.matricula;
cout << "NOmbre:" ;
fflush(stdin);
getline(cin,alumno.nombre);
cout << "dame edad :" ;
cin >> alumno.edad;
FILE *archdisco;
archdisco = fopen("alumnos.dat" ,"at+" );
fwrite(&alumno,sizeof (alumno),1,archdisco);
fclose(archdisco);
}
if (opc==2){
FILE *archdisco;
archdisco = fopen("alumnos.dat" ,"at+" );
while (fread(&alumno,sizeof (alumno),1,archdisco)==1){
cout << " MATRICULA " <<alumno.matricula;
cout << "Nombre " << alumno.nombre;
cout << " MESES " <<alumno.edad<<endl;
}
fclose(archdisco);
}
}
while (opc!=3);
return 0;
}
thanks in advance.
Last edited on Oct 30, 2014 at 4:21pm UTC
Oct 30, 2014 at 5:41pm UTC
while (fread(&alumno,sizeof (alumno),1,archdisco)==1)
This does a memory overwrite of
alumno
. That's ok for built in types (Plain Old Data Types--POD Types), but bad for objects.
You should define stream input/output operators for your type and use those with an fstream.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
#include <ostream>
#include <istream>
#include <fstream>
#include <iostream>
struct Alumno {
int matricula;
std::string nombre;
int edad;
};
std::ostream& operator <<(std::ostream& os, const Alumno& n) {
os << n.matricula << ' ' << n.nombre << ' ' << n.edad;
return os;
}
std::istream& operator >>(std::istream& is, Alumno& n) {
is >> n.matricula >> n.nombre >> n.edad;
return is;
}
int main() {
int opc;
Alumno alumno;
do {
std::cout << "1. Capturar" << std::endl;
std::cout << "2. Mostrar" << std::endl;
std::cin >> opc;
if (opc == 1) {
std::cout << "dame matricula :" ;
std::cin >> alumno.matricula;
std::cout << "NOmbre:" ;
std::cin >> alumno.nombre;
std::cout << "dame edad :" ;
std::cin >> alumno.edad;
std::ofstream f("alumnos.dat" , std::ios_base::app);
f << alumno << std::endl;
}
if (opc == 2) {
std::ifstream f("alumnos.dat" );
Alumno n;
while (f >> n) {
std::cout
<< "MATRICULA " << n.matricula
<< " Nombre " << n.nombre
<< " MESES " << n.edad << std::endl;
}
}
}
while (opc != 3);
return 0;
}
Oct 30, 2014 at 5:57pm UTC
got it, thank you very much.
But now, if instead of showing data, i want to add the data to an objects array or an objects list, how could i do it?
thanks again.
---------------------------------------------------------------------------------------
nvm, i got it... this is just a test code... now im going to use it in my real program, thank you very much.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
#include <ostream>
#include <istream>
#include <fstream>
#include <iostream>
using namespace std;
class Alumno {
public :
int matricula;
string nombre;
int edad;
void Mostrar();
};
void Alumno::Mostrar(){
cout << "MATRICULA " << matricula
<< " Nombre " << nombre
<< " MESES " << edad << endl;
}
ostream& operator <<(ostream& os, const Alumno& n) {
os << n.matricula << ' ' << n.nombre << ' ' << n.edad;
return os;
}
istream& operator >>(istream& is, Alumno& n) {
is >> n.matricula >> n.nombre >> n.edad;
return is;
}
int main() {
int opc;
Alumno alumno;
Alumno alumno2[3];
do {
cout << "1. Capturar" << endl;
cout << "2. Mostrar" << endl;
cin >> opc;
if (opc == 1) {
cout << "dame matricula :" ;
cin >> alumno.matricula;
cout << "NOmbre:" ;
cin >> alumno.nombre;
cout << "dame edad :" ;
cin >> alumno.edad;
ofstream f("alumnos.dat" , ios_base::app);
f << alumno << endl;
}
if (opc == 2) {
int i=0;
ifstream f("alumnos.dat" );
Alumno n;
while (f >> n) {
cout << "MATRICULA " << n.matricula
<< " Nombre " << n.nombre
<< " MESES " << n.edad << endl;
alumno2[i]=n;
i++;
}
for (int j=0;j<3;j++){
alumno2[j].Mostrar();
}
}
}
while (opc != 3);
return 0;
}
btw, why so many people prefers to write "std::" instead of just add "using namespace std" ??
Last edited on Oct 30, 2014 at 7:59pm UTC
Oct 30, 2014 at 8:20pm UTC
Using std::
instead of using namespace std;
creates less overhead. In other words it's more efficient.
Oct 30, 2014 at 8:25pm UTC
want to add the data to an objects array
We'd normally use a vector because it can grow, whereas an array has a fixed length.
std::vector<Alumno> alumno2;
Alternatively STL provides a double threaded linked list
std::list<Alumno> alumno3;
http://en.cppreference.com/w/cpp/container
Oct 31, 2014 at 2:08am UTC
Thank you very much @kbw, you had helped me a lot.
@ostar2 i didnt know that... ill try to do that wey then =) thanks
Oct 31, 2014 at 2:35am UTC
@dual, If you're just making simple programs, it's fine to use namespace.
Oct 31, 2014 at 3:35am UTC
One last thing, how do i know how many "objects" i have on my file?
Also, the vector is not working
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
int main() {
int opc;
Alumno alumno;
vector<Alumno> alumno2;
do {
cout << "1. Capturar" << endl;
cout << "2. Mostrar" << endl;
cin >> opc;
if (opc == 1) {
alumno.Capturar();
ofstream f("alumnos.txt" , ios_base::app);
f << alumno << endl;
}
if (opc == 2) {
int i=0;
ifstream f("alumnos.txt" );
Alumno n;
while (f >> n) {
cout << "MATRICULA " << n.matricula
<< " Nombre " << n.nombre
<< " MESES " << n.edad << endl;
alumno2[i]=n;
i++;
}
}
}
while (opc != 3);
Last edited on Oct 31, 2014 at 3:37am UTC
Oct 31, 2014 at 3:41am UTC
add a counter and increment it each loop.
Oct 31, 2014 at 3:49am UTC
thanks @Pured , it was so easy, i feel so stupid :-/
Topic archived. No new replies allowed.