Hello I am making a simple program which should make an abstract farm with some abstract animals but I have got a problem with reading vector from a file. I was translating most of the project and I deleted some I think unimportant functions and constructors. The program works fine when you 1st time load the vector but it fails after 2nd, 3rd... start. It fails when you try to load farm froma before created file. I am sorry for my english.
this code should be in classes.cpp - i don't know how to write it here
#include<iostream>
#include<string>
#include<vector>
#include<iterator>
#include<fstream>
#include<stdlib.h>
using namespace std;
// declaration of class zviera(animal)
class zviera;
// class farm
class farma{
private :
// meno(name)
std::string meno;
// rozloha(size) - perhaps 945.5 * 749.9 meters
std::pair<double, double> rozloha;
// vector of friend class zviera(animal)
std::vector < zviera > zvery;
public :
// class zviera(animal) is friend class of farma
friend class zviera;
// constructor -----------------------------------------------------
farma() : meno(""), rozloha(0, 0), zvery(0) {}
// pridajZviera(addAnimal) to the vector
void pridajZviera(zviera & z){ zvery.push_back(z); }
friend std::ostream & operator<<(std::ostream & os, const farma & far);
friend std::istream & operator>>(std::istream & is, farma & far);
};
// the class zviera(animal)
class zviera{
private:
// druh(kind of animal)
std::string druh;
// pocet(number of the animals)
int pocet;
// sex of the animals
int pohlavie;
public:
// samec(male), samica(female) the sex of the animal
enum { samec = 0, samica = 1};
// constructor
zviera() :druh(""), pocet(0), pohlavie(0){}
friend std::ostream & operator<<(std::ostream & os, const zviera & zver);
friend std::istream & operator>>(std::istream & is, zviera & zver);
};
// classes.h
#include"classes.cpp"
// Writing values of an animal
std::ostream & operator<<(std::ostream & os, const zviera & zver){
os << "Kind of animal : " << zver.druh;
os << "\nNumber of animals : " << zver.pocet;
os << "\nSex of animal : " << (zver.pohlavie == zver.samec? "male" : "female");
return os;
}
// Setting values of an animal
std::istream & operator>>(std::istream & is, zviera & zver){
std::cout << "Kind : ";
is >> zver.druh;
std::cout << "Number : ";
is >> zver.pocet;
std::cout << "sex(0 - male, 1 - female) : ";
is >> zver.pohlavie;
return is;
}
// Writing saved values of a farm
std::ostream & operator<<(std::ostream & os, const farma & far){
os << "Name of the farm : " << far.meno;
os << "\nSize of the farm : " << far.rozloha.first << " * " << far.rozloha.second << "metres." << std::endl;
os << "Animals on the farm : \n";
std::vector < zviera >::const_iterator it = far.zvery.begin();
for (; it != far.zvery.end(); it++){
os << *it << "\n";
}
return os;
}
// Setting values of a farm
std::istream & operator>>(std::istream & is, farma & far){
std::cout << "Meno farmy je : ";
is >> far.meno;
std::cout << "Rozloha farmy je(a * b metrov) : ";
is >> far.rozloha.first;
is >> far.rozloha.second;
std::cout << " metrov.";
return is;
}
The main.cpp
#include"classes.h"
int main()
{
ofstream fout;
ifstream fin;
int temp = 0;
int tmp = 5;
int tomp = 0;
string nazov;
farma far;
zviera zvero;
while (cin){
cout << "Hello would you like to load your farm from a file?(yes - 1, no - 0, end - 2) ";
cin >> temp;
switch (temp){
case 0:
cout << "Write a name of a file to save your new farm : ";
cin >> nazov;
fout.open(nazov.c_str(), ios_base::out);
cin >> far;
fout.write((char*)&far, sizeof far);
cout << "Would you like to add any animals to your farm?(0 - no, 1 - yes) ";
cin >> tmp;
while (tmp == 1){
switch (tmp){
case 1:cin >> zvero;
far.pridajZviera(zvero);
I meam the problem is probably here:
fout.write((char*)&zvero, sizeof zvero);
cout << "Would you like to add any animals to your farm?(0 - no, 1 - yes) ";
cin >> tmp;
break;
default:
break;
}
}
fout.close();
cout << "Do you wanna see your farm?(0 - no, 1 - yes) ";
cin >> tomp;
if (tomp == 1){
cout << far;
}
break;
case 1:
cout << "Enter name of the file in which is your farm : ";
cin >> nazov;
fin.open(nazov.c_str(), ios_base::in);
The problem may be also here I think
fin.read((char*)&far, sizeof far);
while (fin.read((char*)&zvero, sizeof zvero)){
far.pridajZviera(zvero);
}
cout << far;
fin.close();
break;
case 2: exit(EXIT_SUCCESS);
default: cout << "Wrong value. Enter 0,1 or 2.\n";
break;
}
}
return 0;
}
read
and write
operations are like memcpy
, they make a binary image of the object, and don't follow pointers to subobjects. So you can only use them for trivially copyable objects.
std::vector
and std::string
are NOT trivially copyable. (Objects containing these types are NOT trivially copyable either.) For those, you'll need to fetch and store the length, followed by the data. For std::string
, and std::vector
where the element type is trivially copyable, you can use read
and write
to store the data en masse. Most objects will themselves need to be carefully serialized.