2014-10-15 3 views
-2

Здравствуйте, я делаю простую программу, которая должна создать абстрактную ферму с абстрактными животными , но у меня возникла проблема с чтением вектора из файла. Я переводил большую часть проекта, и я удалил некоторые из них, я думаю, несущественные функции и конструкторы. Программа отлично работает, когда вы в первый раз загружаете вектор, но он терпит неудачу после 2-го, 3-го ... начала. Он не работает, когда вы пытаетесь загрузить ферму froma перед созданным файлом. Прошу прощения за мой английский.Ifstream не умеет читать вектор из файла

этот код должен быть в classes.cpp - я не знаю, как писать здесь

#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; 
    } 

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); 

Я Меам проблемы возможно, здесь:

    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); 

Проблема может быть также здесь Я думаю

   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; 
    } 
+1

Вы определили 'iostream' вставки и извлечения операторов, но вы используете' write', который будет просто писать двоичные данные. – crashmstr

+0

@ user3923130 Слишком много кода! ** Прочитайте ** о [«Минимальные, завершенные, проверенные примеры»] (http://stackoverflow.com/help/mcve). Программа, которую вы написали, может содержать бесконечные проблемы ... но каждый заданный вами вопрос должен сужаться до одной * одной проблемы, которая может быть продемонстрирована. В качестве простого примера: если ваша проблема связана с чтением файлов, то * не включайте приглашение, запрашивающее, хочет ли кто-нибудь прочитать файл или нет *. Просто доведите это до одной проблемы за раз, как просто и коротко, как вы можете это сделать ... вы можете (в идеале) решить свою проблему в этом процессе. – HostileFork

ответ

1

read и write операция, как memcpy, они делают бинарное изображение объекта, а не следует указателям на подобъекты. Поэтому вы можете использовать их только для трехмерных копий объектов.

std::vector и std::string НЕ тривиально можно копировать. (Объекты, содержащие эти типы, не могут быть тривиально скопированы.) Для них вам нужно будет извлечь и сохранить длину, за которой последуют данные. Для std::string и std::vector, где тип элемента тривиально можно копировать, вы можете использовать read и write для хранения данных в массе. Большинство объектов сами должны быть тщательно сериализованы.

+0

Спасибо за ваш ответ, я просто понял, что вы мне скажете. Мой английский не так хорош, как ваш и перевод Google - это ... вы знаете. Еще раз спасибо. – user3923130

0

Переработаны - проблемы решены

classes.h

#include<iostream> 
    #include<string> 
    #include<vector> 
    #include<iterator> 
    #include<fstream> 
    class zviera; 
    class farma{ 
    private: 
     std::string meno; 
     std::pair<double, double> rozloha; 
     std::vector <zviera> zvery; 
    public: 
     friend class zviera; 
     farma() : meno(" "), rozloha(0, 0), zvery(0) {} 
     void zmenRozlohu(const double & a, const double & b){ rozloha.first = a; rozloha.second = b; } 
     void zmenMeno(std::string & s){ meno = s; } 
     void pridajZvery(const std::vector <zviera> zv); 
     friend std::ifstream & operator>>(std::ifstream & fin, farma & far); 
     friend std::ofstream & operator<<(std::ofstream & fout, farma & far); 
     friend std::ostream & operator<<(std::ostream & os, const farma & far); 
     friend std::istream & operator>>(std::istream & is, farma & far); 
    }; 
    class zviera{ 
    private: 
     std::string druh; 
     int pocet; 
     int pohlavie; 
    public: 
     friend class farma; 
     enum { samec = 0, samica = 1 }; 
     zviera() :druh(" "), pocet(0), pohlavie(0){} 
     friend std::ifstream & operator>>(std::ifstream & fin, zviera & zver); 
     friend std::ofstream & operator<<(std::ofstream & fout, zviera & zver); 
     friend std::ostream & operator<<(std::ostream & os, const zviera & zver); 
     friend std::istream & operator>>(std::istream & is, zviera & zver); 
     void setPohlavie(const int & i){ pohlavie = (pohlavie == i) ? 1 : 0; } 
    }; 

classes.cpp

#include"classes.h" 
void farma::pridajZvery(const std::vector <zviera> zv){ 
    zvery.resize(zv.size()); 
    copy(zv.begin(),zv.end(),zvery.begin()); 
} 
std::ostream & operator<<(std::ostream & os, const zviera & zver){ 
    os << "Druh : " << zver.druh; 
    os << "\nPocet zvierat : " << zver.pocet; 
    os << "\nPohlavie : " << (zver.pohlavie == zver.samec ? "samec" : "samica"); 
    return os; 
} 
std::istream & operator>>(std::istream & is, zviera & zver){ 
    std::cout << "Druh : "; 
    is >> zver.druh; 
    std::cout << "Pocet : "; 
    is >> zver.pocet; 
    std::cout << "Pohlavie(0 - samec, 1 - samica) : "; 
    is >> zver.pohlavie; 
    return is; 
} 
std::ifstream & operator>>(std::ifstream & fin, zviera & zver){ 
    getline(fin, zver.druh); 
    fin >> zver.pocet; 
    while (fin.get() != '\n'){ 
     fin.get(); 
    } 
    fin >> zver.pohlavie; 
    while (fin.get() != '\n'){ 
     fin.get(); 
    } 
    return fin; 
} 
std::ifstream & operator>>(std::ifstream & fin, farma & far){ 
    getline(fin, far.meno); 
    fin >> far.rozloha.first; 
    while (fin.get() != '\n'){ 
     fin.get(); 
    } 
    fin >> far.rozloha.second; 
    while (fin.get() != '\n'){ 
     fin.get(); 
    } 
    return fin; 
} 
std::ofstream & operator<<(std::ofstream & fout, farma & far){ 
    fout << far.meno; 
    fout << std::endl; 
    fout << far.rozloha.first; 
    fout << std::endl; 
    fout << far.rozloha.second; 
    fout << std::endl; 
    return fout; 
} 
std::ofstream & operator<<(std::ofstream & fout, zviera & zver){ 
    fout << zver.druh; 
    fout << std::endl; 
    fout << zver.pocet; 
    fout << std::endl; 
    fout << zver.pohlavie; 
    fout << std::endl; 
    return fout; 
} 
std::ostream & operator<<(std::ostream & os, const farma & far){ 
    os << "Nazov farmy : " << far.meno; 
    os << "\nFarma ma rozlohu : " << far.rozloha.first << " * " << far.rozloha.second << "metrov." << std::endl; 
    os << "Zvierata na farme : \n"; 
    if (far.zvery.size() <= 0){ 
     return os; 
    } 
    std::vector <zviera>::const_iterator it = far.zvery.begin(); 
    for (; it != far.zvery.end(); it++){ 
     os << *it << "\n"; 
    } 
    return os; 
} 
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; 
} 

main.cpp

#include"classes.h" 
#include<algorithm> 
#include<stdlib.h> 
using namespace std; 
int main() 
{ 
    int temp = 0; 
    int tmp = 5; 
    int tomp = 0; 
    int len = 0; 
    string nazov; 
    zviera zvero; 
    while (cin){ 
     ofstream fout; 
     cout << "Hello would you like to load your farm from a file?(yes - 1, no - 0, end - 2) "; 
     cin >> temp; 
     switch (temp){ 
     case 0:{ 
      farma far; 
      std::vector <zviera> zve; 
      cout << "Write a name of a file to save your new farm : "; 
      cin >> nazov; 
      fout.open(nazov.c_str(), ios_base::out | ios_base::binary); 
      cin >> 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; 
        zve.push_back(zvero); 
        cout << "Would you like to add any animals to your farm?(0 - no, 1 - yes) "; 
        cin >> tmp; 
        break; 
       default: 
        break; 
       } 
      } 
      len = zve.size(); 
      fout << len; 
      fout << endl; 
      for (int x = 0; x < len; x++){ 
       fout << zve[x]; 
      } 
      fout << far; 
      far.pridajZvery(zve); 
      fout.close(); 
      cout << "Do you wanna see your farm?(0 - no, 1 - yes) "; 
      cin >> tomp; 
      if (tomp == 1){ 
       cout << far; 
      } 
      break; 
     } 
     case 1:{ 
      ifstream fin; 
      farma kar; 
      std::vector <zviera> zvert; 
      cout << "Enter name of the file in which is your farm : "; 
      cin >> nazov; 
      fin.open(nazov.c_str(), ios_base::in | ios_base::binary); 
      fin >> len; 
      while (fin.get() != '\n') 
       fin.get(); 
      zvert.resize(len); 
      for (int x = 0; x < len; x++){ 
       fin >> zvert[x]; 
      } 
      fin >> kar; 
      kar.pridajZvery(zvert); 
      cout << kar; 
      fin.close(); 
      break; 
     } 
     case 2: exit(EXIT_SUCCESS); 
     default: cout << "Wrong value. Enter 0,1 or 2.\n"; 
      break; 
     } 
    } 

    return 0; 
}