Перейти к содержимому

Как записать вектор в файл c

  • автор:

Как записать вектор в файл c

Здравствуйте. Возникла такая проблема: У меня есть свой класс

class CType < public: CType () AnsiString type_var; AnsiString name_type; AnsiString name_var; bool is_empty; bool is_show; bool visible; >;

я создаю вектор из элементов этого класса, в ходе выполнения программы его элементы меняются.

Как мне сохранить этот вектор в файл, чтобы в дальнейшем я мог его загрузить?

Пробовал такой вариант:

vector to_save(100);
std::ofstream out_file("vector.bin", std::ios::binary | std::ios::out); out_file.write((const char*)&to_save.front(), to_save.size() * sizeof(CType));

Сохранение произошло, файл создался.

to_save.resize(100); std::ifstream in_file("vector.bin", std::ios::binary); in_file.read((char*)&to_save.front(), to_save.size() * sizeof(CType));

загрузка тоже происходит, но при попытке получить данные из этого вектора появляется «Acces violation. «.

Как я понял, вся проблема в том, что в моем классе содержатся элементы AnsiString, если их заменить, например, на int, то все работает нормально.

David Villa
Посмотреть профиль
Найти ещё сообщения от David Villa

Как записать вектор в файл c

Всем привет!
Собсна интересует сабж. Поиск мало что дал по форуму, т.к. законченного пояснения с примером я не нашёл. А из того что есть, достаточно тривиально.
Но, вы же понимаете, как правило, в основном происходит так:
— считали из файла
— что-то поделали с этими данными (добавили, удалили, модифицировали)
— записали обратно

Хотелось бы:
— я уже считал файл в вектор
— теперь хочу при пробегании по элементам контейнера что-то поделать с элементом (модифицировать, проверить, пропустить и т.д.) и записать его в файл (может и пропустить, незаписывать).

typedef std::vector _STRING_LIST;
.
_STRING_LIST v; // здесь уже что-то есть, он готов для вывода

std::ofstream output_buffer(lpszFileName, std::ios::out);

CFileWriter fileWriter(&output_buffer);
std::for_each(input_file_lines.begin(), input_file_lines.end(), fileWriter);

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

Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!

Re: Запись вектора в файл

От: _Dreamer
Дата: 29.12.06 08:02
Оценка:

Здравствуйте, Smooky, Вы писали:

S>Хотелось бы:
S>- я уже считал файл в вектор
S>- теперь хочу при пробегании по элементам контейнера что-то поделать с элементом (модифицировать, проверить, пропустить и т.д.) и записать его в файл (может и пропустить, незаписывать).

S>Но мне так не нравится, научите пользоваться std::transform или как прибиндить функцию.
S>Т.е. чтобы при записи каждого элемента контейнера проделывались какие та действия с элементом, и потом уже решалось, записывать его туда или нет.

#include #include #include bool predicate( const std::string& str ) // здесь решаем, надо ли записывать в файл < return str == "hello"; > void func() < std::vectorvstrings; // заполняем вектор std::ofstream ofile( "output.txt" ); std::remove_copy_if( vstrings.begin(), vstrings.end(), std::ostream_iterator< std::string >( ofile ), predicate ); >

Re[2]: Запись вектора в файл

От: Smooky
Дата: 29.12.06 08:36
Оценка:
_D>#include _D>#include _D>#include _D>bool predicate( const std::string& str ) // здесь решаем, надо ли записывать в файл _D> < _D>return str == "hello"; _D>> _D>void func() _D> < _D>std::vector vstrings; _D> // заполняем вектор _D> std::ofstream ofile( "output.txt" ); _D> std::remove_copy_if( _D> vstrings.begin(), _D> vstrings.end(), _D> std::ostream_iterator< std::string >( ofile ), _D> predicate ); _D>> _D>

Ага, спасибо, работает. буду щас разбирацца, как это работает.
Осваиваю STL, понимаю, штука мощьная, сила. но надо научицца пользовацца. к сожалению источников и полезных доков очень мало.

Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!

Re[3]: Запись вектора в файл

От: vkjr hookahmixes.com/ru
Дата: 29.12.06 09:27
Оценка:

Читай Джосаттиса «С++ Стандартная библиотека», там очень много полезной информации.

> Ага, спасибо, работает. буду щас разбирацца, как это работает.
> Осваиваю STL, понимаю, штука мощьная, сила. но надо научицца пользовацца. к сожалению источников и полезных доков очень мало.

Posted via RSDN NNTP Server 2.0
Re[4]: Запись вектора в файл

От: Smooky
Дата: 29.12.06 09:43
Оценка:

Здравствуйте, vkjr, Вы писали:

V>Читай Джосаттиса «С++ Стандартная библиотека», там очень много полезной информации.

>> Ага, спасибо, работает. буду щас разбирацца, как это работает.
>> Осваиваю STL, понимаю, штука мощьная, сила. но надо научицца пользовацца. к сожалению источников и полезных доков очень мало.

Да, читаю. вот сделал как у Мейэрса. но почему та не работает

// Читаем в вектор из текстового файла только те строки, длина которых больше 32 // v = пустой bool IsCorrectStringLength(const std::string& str) < return (str.length() > 32); > templatetypename _X, typename _Y, typename _Pred> _Y copy_if(_X begin, _X end, _Y dest, _Pred p) < while (begin != end) < if (p(*begin)) *dest++=*begin; ++begin; > return dest; > . typedef std::vector _STRING_LIST; _STRING_LIST v; std::ifstream input_buffer(lpszFileName, std::ios::in); std::istream_iterator fileBegin(input_buffer); std::istream_iterator fileEnd; copy_if(fileBegin, fileEnd, v(), IsCorrectStringLength);

Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!

Re[5]: Запись вектора в файл

От: Stepkh
Дата: 29.12.06 10:52
Оценка:

Здравствуйте, Smooky, Вы писали:

S>Здравствуйте, vkjr, Вы писали:

V>>Читай Джосаттиса «С++ Стандартная библиотека», там очень много полезной информации.

>>> Ага, спасибо, работает. буду щас разбирацца, как это работает.
>>> Осваиваю STL, понимаю, штука мощьная, сила. но надо научицца пользовацца. к сожалению источников и полезных доков очень мало.

S>Да, читаю. вот сделал как у Мейэрса. но почему та не работает

S>.

S>typedef std::vector _STRING_LIST;
S>_STRING_LIST v;

S>std::ifstream input_buffer(lpszFileName, std::ios::in);
S>std::istream_iterator fileBegin(input_buffer);
S>std::istream_iterator fileEnd;

S>copy_if(fileBegin, fileEnd, v(), IsCorrectStringLength);

copy_if(fileBegin, fileEnd, back_inserter(v), IsCorrectStringLength);

Сохранить vector в файл и считать оттуда [закрыт]

Закрыт. Этот вопрос необходимо уточнить или дополнить подробностями. Ответы на него в данный момент не принимаются.

Хотите улучшить этот вопрос? Добавьте больше подробностей и уточните проблему, отредактировав это сообщение.

Закрыт 6 лет назад .
Имеется структура:

struct str < int a; bool b; >; 

Также есть вторая:

struct str2 < int c; int d[5]; std::vectorvec; >; 

На её основе строится вектор:

std::vectorvec_2; 

Нужно сохранить этот вектор в файл, а также считать из файла обратно в память.
Отслеживать
51.6k 201 201 золотой знак 63 63 серебряных знака 245 245 бронзовых знаков
задан 25 авг 2017 в 13:51
11 1 1 серебряный знак 1 1 бронзовый знак

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Для начала нужно определить методы чтения/записи вашей структуры. Для этой цели хорошо подходят операторы > .

std::ostream& operator <<(std::ostream &os, const str &value)< os << value.a << value.b; return os; >std::istream& operator>>(std::istream &is, str &value)< is >> value.a >> value.b; return is; > 

Теперь писать структуру в файл можно так:

std::fstream ofs("file"); str s; ofs  
std::fstream ifs("file"); str s; ifs >> s; 

Чтобы записать вектор структур в файл, можно сделать так:

std::fstream ofs("file"); std::vector v = ; std::copy(v.begin(), v.end(), std::ostream_iterator(ofs)); 

Чтобы прочитать вектор структур, можно сделать так:

std::fstream ifs("file"); std::vector v; std::copy(std::istream_iterator(ifs), std::istream_iterator(), std::back_inserter(v)); 

Это была инструкция для str . Вам нужно выполнить аналогичные действия и для str2 .

Отслеживать
ответ дан 25 авг 2017 в 19:30
yrHeTateJlb yrHeTateJlb
8,052 15 15 серебряных знаков 35 35 бронзовых знаков

То, что вы хотите, называется сериализациея/десериализация. Существует довольно много решений на этот счет, например, boost::serialization.

Одним из простых кросплатформенных способов сериализации является использование QDataStream и перегрузка operator > для пользовательских типов. Любой массив записывается в виде

stream ; for(auto&& x: array) stream  

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

QDataStream& operator  QDataStream& operator >> (QDataStream& stream, const str& rha)< int64_t a; // Нужен платформонезависимый тип stream >> a; rha.a = a; stream >> rha.b; return stream; > str str_1 ; str str_2; < File file("file.dat"); file.open(QIODevice::WriteOnly); QDataStream out(&file); out < File file("file.dat"); file.open(QIODevice::ReadOnly); QDataStream in(&file); in >> str2; > 

Для обработки ошибок можно бросать исключения (без этого есть шанс заполнить все структуры нулями и долго искать ошибку).

Строки таким образом сериализовывать нельзя, нужно преобразовывать их в нормальный массив, например, в utf8, и уже его записывать, т.к. чтение и запись строк в потоки обычно не симметричны.

То же самое можно делать и со стандартными потоками, но там есть проблема с кросплатформенностью.

Как записать вектор в файл c

Потоки для работы с текстовыми файлами представляют объекты, для которых не задан режим открытия ios::binary .

Запись в файл

Для записи в файл к объекту ofstream или fstream применяется оператор
#include #include int main() < std::ofstream out; // поток для записи out.open("hello.txt"); // открываем файл для записи if (out.is_open()) < out out.close(); std::cout

Здесь предполагается, что файла "hello.txt" располагается в одной папке с файлом программы. Данный способ перезаписывает файл заново. Если надо дозаписать текст в конец файла, то для открытия файла нужно использовать режим ios::app :

std::ofstream out("hello.txt", std::ios::app); if (out.is_open()) < out out.close();

Чтение из файла

Если надо считать всю строку целиком или даже все строки из файла, то лучше использовать встроенную функцию getline() , которая принимает поток для чтения и переменную, в которую надо считать текст:

#include #include #include // для std::getline int main() < std::string line; std::ifstream in("hello.txt"); // окрываем файл для чтения if (in.is_open()) < while (std::getline(in, line)) < std::cout > in.close(); // закрываем файл >

Также для чтения данных из файла для объектов ifstream и fstream может применяться оператор >> (также как и при чтении с консоли):

#include #include #include struct Point < Point(double x, double y): x, y <> double x; double y; >; int main() < std::vectorpoints< Point, Point, Point>; std::ofstream out("points.txt"); if (out.is_open()) < // записываем все объекты Point в файл for (const Point& point: points) < out > out.close(); std::vector new_points; std::ifstream in("points.txt"); // окрываем файл для чтения if (in.is_open()) < double x, y; while (in >> x >> y) < new_points.push_back(Point); > > in.close(); for (const Point& point: new_points) < std::cout >

Здесь вектор структур Point записывается в файл.

for (const Point& point: points)

При чем при записи значений переменных файл они отделяются пробелом. В итоге будет создаваться файл в формате

0 0 4 5 -5 7

Используя оператор >>, можно считать последовательно данные в переменные x и y и ими инициализировать структуру.

double x, y; while (in >> x >> y) < new_points.push_back(Point); >

Но стоит отметить, что это ограниченный способ, поскольку при чтении файла поток in использует пробел для отделения одного значения от другого и таким образом считывает эти значения в переменные x и y. Если же нам надо записать и затем считать строку, которая содержит пробелы, и какие-то другие данные, то такой способ, конечно, не сработает.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *