Vector С++

Не подскажите в чем все-таки дело?

VS обычно показывает где вылет.

Снимок

Вот это вылетает, пишет что в самом конце блока со считыванием из бинарного файла. Причем у меня все организовано так, что я могу вводить данные пока не нажму выход. Так вот если я не выхожу из программы, то все нормально читается и не вылетает, потом можно продолжать добавлять и опять это читать, но ошибка вылетает при выходе. Но зато при каждом последующем запуске и выборе "читать из бинарного файла, программа тут же вылетает и появляется еще лишняя строчка.

В С++ нельзя так, по крайней мере если в классе что-то более сложное, чем простые типы (int, …) и статичные массивы.

Надо самому в байты все нужные значения конвертировать, и обратно.

А зачем и текстовый, и бинарный?)

Сказали, что в идеале сделать два, второй вариант по приоритету - бинарник, а самый плохой вариант - текстовый

Нашел я что-то на просторах сети интернет, попытался переделать под себя

void loadBin(fstream& fs)
	{
		fs.read((char*)&id, sizeof(int));  

		size_t len_name;                         
		fs.read((char*)&len_name, sizeof(len_name));  
		char* buf1 = new char[len_name];         
		fs.read(buf1, len_name);                   
		name = buf1;

		size_t len_sname;
		fs.read((char*)&len_sname, sizeof(len_sname));
		char* buf2 = new char[len_sname];
		fs.read(buf2, len_sname);
		surname = buf2;

		size_t len_adds;
		fs.read((char*)&len_adds, sizeof(len_adds));
		char* buf3 = new char[len_adds];
		fs.read(buf3, len_adds);
		adds = buf3;

		size_t len_numb;
		fs.read((char*)&len_numb, sizeof(len_numb));
		char* buf4 = new char[len_numb];
		fs.read(buf4, len_numb);
		number = buf4;

		delete[]buf1;
		delete[]buf2;
		delete[]buf3;
		delete[]buf4;
	}

А потом в мейне как-то вроде

vector<Phone_book>cont;
			fstream fs("Phone_book.bin", ios::in | ios::binary);
			if (fs.is_open())
				fs.read((char*)&obj, sizeof(Phone_book));
			for (int i = 0; i < contacts.size(); ++i)
			{
				cont[i].loadBin(fs);
			}
			for (int i = 0; i < cont.size(); ++i)
			{
				cout << cont[i].getID() << " " << cont[i].getName() << " " << cont[i].getSurname() << " " << cont[i].getAddress() << " " << cont[i].getNumber() << endl;
			}

Только оно не работает и я не совсем понимаю что тут вообще происходит!

Так надо сначала сохранить в этом формате )

4 раза читается число (размер данных) и массив байтов этого размера.

Надо примерно отсюда искать: https://www.google.com/search?q=c%2B%2B+save+object+to+binary+file

Я в тупике. Нашел на stackoverflow вот такой код. Пытаюсь его переделать под себя с вектором. Но ничего не выходит:

#include <string>
#include <iostream>
#include <fstream>

using namespace std;

class Test
{
public:
    Test(const char * a = "",
         const char * b = "",
         const char * c = "")
        :a(a),b(b),c(c){}

    void write(ostream&f) const
    {
        writeStr(a,f);
        writeStr(b,f);
        writeStr(c,f);
    }
    void read(istream&f)
    {
        readStr(a,f);
        readStr(b,f);
        readStr(c,f);
    }


    friend ostream& operator << (ostream&f, const Test&t)
    {
        return f << "(" << t.a << "," << t.b << "," << t.c << ")";
    }

private:
    string a, b, c;
    static void writeStr(const string& s, ostream& f)
    {
        size_t l = s.length();
        f.write((const char*)&l,sizeof(size_t));
        f.write(s.data(),l);
    }
    static void readStr(string& s, istream&f)
    {
        size_t l;
        f.read((char*)&l,sizeof(size_t));
        char * str = new char[l+1];
        f.read(str,l);
        str[l] = 0;
        s = str;
        delete[] str;
    }
};

int main(int argc, const char * argv[])
{
    Test x("x","1","2"), y("y","3","4");
    Test u,v;
    cout << u << "\n" << v << "\n\n";

    {
        ofstream out("data",ios::binary);
        x.write(out);
        y.write(out);
    }
    {
        ifstream in("data",ios::binary);
        u.read(in);
        v.read(in);
    }
    cout << u << "\n" << v << "\n\n";

}

Памагите!!!

Надо сначала понять что вообще сделать надо, придумать формат файла, из которого потом можно будет прочитать и восстановить состояние.

Раз уже есть функции записи/чтения строк, и в объектах только поля имя, адрес и т.п., то можно просто писать все поля объекта как тут и есть

потом читать их так же и создавать объекты пока не кончится файл.

Вообще уже не понимаю, что нужно делать. Написал какую-то чушь. Ничего не работает. В текстовый файл пишет неправильно, с бинарным вообще непонятно. Если вам не сложно, посмотрите пожалуйста и скажите, что нужно сделать, чтобы оно читалось и записывалось нормально. У меня ступор с этим заданием какой-то.

#include<iostream>
#include<string>
#include<fstream>
#include<vector>

using namespace std;

class Phone_book
{
	static int s_id;
	string id;
	string name;
	string surname;
	string adds;
	string number;
	static void save(const string& str, fstream& fs)
	{
		size_t len = str.size();
		fs.write((const char*)&len, sizeof(size_t));
		fs.write(str.data(), len);
	}
	static void load(string& str, fstream& fs)
	{
		size_t len;
		fs.read((char*)&len, sizeof(size_t));
		char* string = new char[len + 1];
		fs.read(string, len);
		str[len] = 0;
		str = string;
		delete[] string;
	}
public:
	Phone_book(const char* id = "", const char* name = "", const char* surname = "", const char* adds = "", const char* number = "")
	{
		this->id = id;
		this->name = name;
		this->surname = surname;
		this->adds = adds;
		this->number = number;
	}
	const string& getID()const
	{
		return id;
	}
	const string& getName()const
	{
		return name;
	}
	const string& getSurname()const
	{
		return surname;
	}
	const string& getAddress()const
	{
		return adds;
	}
	const string& getNumber()const
	{
		return number;
	}
	void setID(const string& id)
	{
		this->id = id;
	}
	void setName(const string& name)
	{
		this->name = name;
	}
	void setSurname(const string& surname)
	{
		this->surname = surname;
	}
	void setAddress(const string& adds)
	{
		this->adds = adds;
	}
	void setNumber(const string& number)
	{
		this->number = number;
	}
	void setContact()
	{
		cout << "Enter contact details: " << endl;
		cout << "Name: " << endl; getline(cin, name);
		cout << "Surname: " << endl; getline(cin, surname);
		cout << "Address: " << endl; getline(cin, adds);
		cout << "Phone Number: " << endl; getline(cin, number);
	}
	void write(fstream& fs) const
	{
		save(id, fs);
		save(name, fs);
		save(surname, fs);
		save(adds, fs);
		save(number, fs);
	}
	void read(fstream& fs)
	{
		load(id, fs);
		load(name, fs);
		load(surname, fs);
		load(adds, fs);
		load(number, fs);
	}
	void show()
	{		
		cout << id << " " << name << " " << surname << " " << adds << " " << number << endl;		
	}
	friend ostream& operator << (fstream& fs, const Phone_book& ph)
	{
		return fs << ph.id << " " << ph.name << " " << ph.surname << " " << ph.adds << " " << ph.number;
	}
};
int main()
{
	static int s_id = 1;
	vector<Phone_book>contacts;
	Phone_book obj;
	string res;
	fstream fs;
	bool exit = true;
	int action = 0;
	do
	{
		obj.setContact();
		obj.setID(to_string(s_id));
		s_id++;
		contacts.push_back(obj);
		cout << "Enter new data(1 - Yes, 0 - No)\n";
		cin >> exit;
		cin.get();
	} while (exit);
	do
	{
		if (exit == false)
		{
			cout << "Select action: " << endl;
			cout << "1. Delete contact;" << endl;
			cout << "2. Save information about phone contacts to text file" << endl;
			cout << "3. Save information about phone contacts to binary file" << endl;
			cout << "4. Load information about phone contacts from text file;" << endl;
			cout << "5. Load information about phone contacts from binary file;" << endl;
			cout << "6. Exit the program." << endl;
			cin >> action;
			cin.get();
			if (action == 1)
			{
				int pos;
				for (int i = 0; i < contacts.size(); i++)
				{
					cout << "Position " << i << ": ";
					contacts[i].show();
				}
				cout << "Enter the position of the contact you want delete:" << endl;
				cin >> pos;
				if (pos > contacts.size() - 1 || pos < 0)
					cout << "Wrong position" << endl;
				else
				{
					contacts.erase(contacts.begin() + pos);

				}
				for (int i = 0; i < contacts.size(); i++)
				{
					contacts[i].show();
				}
			}
			else if (action == 2)
			{
				res = obj.getID() + " " + obj.getName() + " " + obj.getSurname() + " " + obj.getAddress() + " " + obj.getNumber();
				try
				{
					fs.open("Phone_book.txt", ios::ate|ios::out);
					if (!fs.is_open())
						throw logic_error("Phone_book.txt can not be opened");
					fs << res << endl;
					fs.close();
				}
				catch (logic_error & ex)
				{
					cerr << "Error: " << ex.what() << endl;
				}
			}
			else if (action == 3)
			{
				fstream fs("Phone_book.bin", ios::out | ios::binary);
				for (int i = 0; i < contacts.size(); i++)
				{
					contacts[i].write(fs);
				}
			}
			else if (action == 4)
			{
				fstream fs("Phone_book.txt", ios::in);
				string s;
				while (getline(fs, s))
				{
					cout << s << endl;
				}
				fs.close();
			}
			else if (action == 5)
			{
				vector<Phone_book>cont;
				Phone_book obj2;
				fstream fs("Phone_book.bin", ios::in | ios::binary);
				if (fs.is_open())
				{
					while (!fs.eof())
					{
						obj2.read(fs);
						cont.push_back(obj2);
					}	
				}
				for (int i = 0; i < cont.size(); ++i)
				{
					cont[i].show();
				}
			}
			else if (action<1||action>6)
				cout << "Wrong choice!" << endl;			
		}

	} while (action != 6);
	
	return 0;
}

А что пишет?

И в нем что получается? Можно посмотреть любым HEX-редактором (чтобы было проще смотреть — вводить только англ. буквы). Строки тут пишутся в виде размер (4 байта, или 8 если 64 бит) + символы.

Если это запись в текстовый файл, то непонятно где чтение.
И я бы не парился с операторами, а просто сделал функции типа writeToBinFile, readFromBinFile, writeToTextFile, readFromTextFile. Иначе например непонятно чем один вид файлов (и надо помнить какой из них) заслужил операторы.

1 vasya pupkin street 36925874 2 elenaa ivanova avenua 3698524

Вот что записывается в бинарник (я записал два значения), а при выводе вылетает все.
В текстовый из двух записей записывается только последний контакт и в консоль выводится соответственно он же.

Так а тут и записывается один последний, а не все.

Почему-то странные символы в виде прямоугольников тут пропадают

Тут 0 не туда присваивается, в примере ж было

Чтобы не путаться я бы переименовал переменную, в которую из файла чтение, в например strBytes

Я понимаю как это должно происходить в массиве, с вектором не могу понять вообще.

for (int i = 0; i < 12; ++i)
			{
				str[i] = "Some text ";
				fs << str[i] << endl;
			}

Как это организовать в векторе?

Так же как с бин?)


Код всё еще зачем-то путает читателей, говорит, что в массиве хранятся телефонные книги, а не контакты.

Я совсем запутался и ничего не понимаю уже

Если я так же запишу, то запишутся непонятные символы и выведутся на экран

Ну дык для текстового надо вызывать функцию записи текста, а не бин.