Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Запись вектора в файл


Автор: nenormativ 14.9.2009, 20:41
не как не могу разобраться как можно нормально записать и сохранить масив (вектор) структур в файл и загрузить его оттуда...
Код

struct Date{
    int day;
    int month;
    int year;
    int hours;
    int min;
}s_date;
struct Event{
    string _event;
void main(){
vector<Date> date;
    vector<Event> ev;
    AddDate(s_date);\\функция добавления даты
    AddEvent(s_event);\\ф-я добавления события
    date.push_back(s_date);
    ev.push_back(s_event);
}

вот к примеру я имею 3 вектора date и 3 вектора ev...каким образом их лучше всего записать в файл и загрузить оттуда...
вот для записи применял такое:
Код

void SaveToFile(vector<Date> &vec,vector<Event> &ev)
{
    ofstream out("test123.txt");
    vector<Date>::iterator vecBegin;
    vector<Event>::iterator evBegin;
    for(evBegin=ev.begin(),vecBegin=vec.begin();vecBegin!=vec.end();vecBegin++,evBegin++)
    {
        out<<&vecBegin<<&evBegin<<endl;
    }
    out.close();
}

и еще пробовал вариант с FILE*f
вороди записывает нормально,но никак не могу нормально считать из файла,помогите плиз


Модератор: Название темы должно отражать ее суть!

Автор: iRUSH 14.9.2009, 20:48
Код

void SaveToFile(vector<Date> &vec,vector<Event> &ev)
{
    ofstream out("test123.txt");
    vector<Date>::iterator vecBegin;
    vector<Event>::iterator evBegin;
    for(evBegin=ev.begin(),vecBegin=vec.begin();vecBegin!=vec.end();vecBegin++,evBegin++)
    {
        out << *vecBegin << *evBegin << endl;
    }
    out.close();
}

Может так(только возможно тогда у структур нужно будет переопределить оператор << и >>)? и Вообще у тебя какаято логика сохранения неправильная, проще сначало сохранить в файл размер массива, затем данные, потом размер второго массива, затем его данные, когда считываешь, сначало читаеш размер первого массива, его данные ну и соответственно размер второго массива, и его данные...

Автор: nenormativ 14.9.2009, 21:06
Цитата(iRUSH @ 14.9.2009,  20:48)
Код

void SaveToFile(vector<Date> &vec,vector<Event> &ev)
{
    ofstream out("test123.txt");
    vector<Date>::iterator vecBegin;
    vector<Event>::iterator evBegin;
    for(evBegin=ev.begin(),vecBegin=vec.begin();vecBegin!=vec.end();vecBegin++,evBegin++)
    {
        out << *vecBegin << *evBegin << endl;
    }
    out.close();
}

Может так(только возможно тогда у структур нужно будет переопределить оператор << и >>)? и Вообще у тебя какаято логика сохранения неправильная, проще сначало сохранить в файл размер массива, затем данные, потом размер второго массива, затем его данные, когда считываешь, сначало читаеш размер первого массива, его данные ну и соответственно размер второго массива, и его данные...

пробовал так:
Код

FILE*f=fopen("test.txt","wb+");
vector<Date>::iterator vecBegin;
vector<Event>::iterator evBegin;
for(vecBegin=vec.begin(),evBegin=ev.begin();vecBegin!=vec.end();vecBegin++,evBegin++)
{
    fwrite(&vecBegin,sizeof(vector<Date>),1,f);
    fwtite(&evBegin,sizeof(vector<Event>),1,f);
}
fclose(f);

но так же не особо получалось,данные считывались только в новый вектор,и то если они были сохранены/считаны при запущеном приложение,если к примеру записать данные,и закрыть приложение,то потом никак считать не получается...вечно ошибки вылетают

Автор: bsa 14.9.2009, 21:09
nenormativ, во-первых, как ты собираешься хранить их в файле? В двоичном виде или в текстовом? Если в двоичном, то все очень просто делается, практически даже ничего писать не надо для POD типов. А вот в случае текстового, тут нужно будет кое-что дописать.

Начнем с того, что у тебя, скорее всего, структура классов неверная. Логичней всего сделать один вектор событий. А событие уже пусть содержит и время и текст:
Код
struct Time
{
    int day;
    int month;
    int year;
    int hours;
    int min;
};

struct Event
{
    Time time;
    std::string text;
};
Затем, чтобы можно было легко работать с потоками нужно ввести пару перегрузок операторов:
Код
std::ostream& operator<<(std::ostream &stream, const Time &time)
{
   stream << time.day << '.' << time.month << '.' << time.year << ' ';
   stream << time.hours << ':' << std::setw(2) << std::setfill('0') << time.min;
   return stream;
}

std::ostream& operator<<(std::ostream &stream, const Event &event)
{
   return stream << event.time << '\t' << event.text;
}
Что позволит сохранять в файл одной командой:
Код
std::copy(ev.begin(), ev.end(), std::ostream_iterator<Event>(out, "\n"));
Так же, если перегрузить operator>> для обоих классов, то можно будет аналогично загружать данные из файла:
Код
std::copy(std::istream_iterator<Event>(in), std::istream_iterator<Event>(), std::back_inserter(ev));

Автор: nenormativ 14.9.2009, 21:24
Цитата(bsa @ 14.9.2009,  21:09)
nenormativ, во-первых, как ты собираешься хранить их в файле? В двоичном виде или в текстовом? Если в двоичном, то все очень просто делается, практически даже ничего писать не надо для POD типов. А вот в случае текстового, тут нужно будет кое-что дописать.

Начнем с того, что у тебя, скорее всего, структура классов неверная. Логичней всего сделать один вектор событий. А событие уже пусть содержит и время и текст:
Код
struct Time
{
    int day;
    int month;
    int year;
    int hours;
    int min;
};

struct Event
{
    Time time;
    std::string text;
};
Затем, чтобы можно было легко работать с потоками нужно ввести пару перегрузок операторов:
Код
std::ostream& operator<<(std::ostream &stream, const Time &time)
{
   stream << time.day << '.' << time.month << '.' << time.year << ' ';
   stream << time.hours << ':' << std::setw(2) << std::setfill('0') << time.min;
   return stream;
}

std::ostream& operator<<(std::ostream &stream, const Event &event)
{
   return stream << event.time << '\t' << event.text;
}
Что позволит сохранять в файл одной командой:
Код
std::copy(ev.begin(), ev.end(), std::ostream_iterator<Event>(out, "\n"));
Так же, если перегрузить operator>> для обоих классов, то можно будет аналогично загружать данные из файла:
Код
std::copy(std::istream_iterator<Event>(in), std::istream_iterator<Event>(), std::back_inserter(ev));

спасибо огромное за помощь,сейчас буду пробовать. Прошу прощения за мою неграмотность smile 

Автор: bsa 15.9.2009, 10:24
так:
Код
stream >> var1 >> '.' >> var2 >> '.' >> var3;
нельзя. На это и ругается компилятор. Напиши собственную функцию, которая бы пропускала ненужные символы, используя stream.peek() и stream.get().

Автор: nenormativ 15.9.2009, 21:25
Спасибо огромное за помощь!!!Все получилось и работает smile 

Автор: bsa 15.9.2009, 21:48

M
bsa
nenormativ, если ответ на вопрос получен, то пометь тему решенной

Автор: nenormativ 15.9.2009, 22:28
хорошо smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)