Не подскажите в чем все-таки дело?
Вот это вылетает, пишет что в самом конце блока со считыванием из бинарного файла. Причем у меня все организовано так, что я могу вводить данные пока не нажму выход. Так вот если я не выхожу из программы, то все нормально читается и не вылетает, потом можно продолжать добавлять и опять это читать, но ошибка вылетает при выходе. Но зато при каждом последующем запуске и выборе "читать из бинарного файла, программа тут же вылетает и появляется еще лишняя строчка.
В С++ нельзя так, по крайней мере если в классе что-то более сложное, чем простые типы (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;
}
Как это организовать в векторе?
Так же как с бин?)
Код всё еще зачем-то путает читателей, говорит, что в массиве хранятся телефонные книги, а не контакты.
Я совсем запутался и ничего не понимаю уже
Если я так же запишу, то запишутся непонятные символы и выведутся на экран
Ну дык для текстового надо вызывать функцию записи текста, а не бин.