Как считать вектор из файла c
Столкнулся с проблемой, нужно вектор ввести в файл, а потом вывести оттуда.
Делаю я как написано в книге (блочный ввод/вывод), но там не для векторов, а для массива.
Записываю в файл:
Извлекаю из файла
Синтаксической ошибки нет, но. я коментну строку с ошибкой.
Как сделать это правильно?
Здравствуйте, Psihadelic, Вы писали:
Здравствуйте, Psihadelic, Вы писали:
P>Столкнулся с проблемой, нужно вектор ввести в файл, а потом вывести оттуда.
P>Делаю я как написано в книге (блочный ввод/вывод), но там не для векторов, а для массива.
А если бы в книге был не массив, а указатель (на массив)? Получился бы точно такой же эффект с вылетом.
vector — это объект, хранящий свой массив по указателю.
Записывать out.write(&MasSt, sizeof(MasSt)) бессмысленно, так в файле окажется несколько адресов и чисел, но не сами элементы.
После чтения, эти адреса будут указывать в никуда.
¹) только в том случае, если students — это POD-тип. К примеру, std::string и std::vector — не POD.
Спасибо большое! Конечно не всё понял, но спасибо! Про сериализацию почитал на МСДН, теперь хоть знаю что это такое, но в суть не очень вник, инфы было мало, а читать форум мне пока ещё сложно (не тот уровень знаний).
Не знаю, что такое POD-тип, но у меня students это простой класс.
Хочу задать парочку вопросов:
1) что такое size_t ?
2) out.write((const char*)&count, sizeof(count)); // сохраняем количество
зачем нам сохранять количество элементов и можно ли написать это одной строкой?
3) зачем читать количество? in.read((char*)&count, sizeof(count)); // читаем количество
4) MasSt.resize(count); // резервируем
резервируем. кол-во элементов, но зачем резервируем, куда и что вообще это значит?)
Здравствуйте, Psihadelic, Вы писали:
P>Спасибо большое! Конечно не всё понял, но спасибо! Про сериализацию почитал на МСДН, теперь хоть знаю что это такое, но в суть не очень вник, инфы было мало, а читать форум мне пока ещё сложно (не тот уровень знаний).
P>Не знаю, что такое POD-тип, но у меня students это простой класс.
Гугл в помощь.
Если коротко, это такой тип, объекты которого можно копировать побайтово. Plain Old Data — "старые добрые простые данные".
P>Хочу задать парочку вопросов:
P>1) что такое size_t ?
Стандартный тип для представления размеров данных.
Аналог unsigned int, грубо говоря. (Тонкости возникают на 64-битных платформах LLP64 и LP64, где sizeof(int)=4, sizeof(size_t)=8).
P>2) out.write((const char*)&count, sizeof(count)); // сохраняем количество
P> зачем нам сохранять количество элементов и можно ли написать это одной строкой?
Затем, что мы же должны оставить потомкам сведения: сколько элементов в массиве.
У нас есть 3 стратегии: префиксная, инфиксная, суффиксная.
Префиксная — записать "сколько", а потом элементы.
Суффиксная — записать элементы и в конце особый завершающий элемент. Например, студента с пустым именем.
Инфиксная — записать последовательность, в которой чередуются маркеры (продолжение/конец) и элементы: что-то вроде "+", элемент, "+", элемент, "+", элемент, "-".
Соответственно, чтение
Префиксная — прочитать "сколько", затем прочитать столько элементов подряд.
Суффиксная — читать элементы поштучно и проверять, не является ли очередной признаком конца.
Инфиксная — читать маркеры и элементы поштучно; когда прочитан маркер конца, не пытаться прочесть следующий элемент (его там нет).
P>3) зачем читать количество? in.read((char*)&count, sizeof(count)); // читаем количество
Чтобы узнать, сколько элементов следует за ним в файле.
Только в том случае, если размер элемента в файле постоянный, и ничего иного в файле нет, — можно взять размер файла и поделить на размер элемента.
P>4) MasSt.resize(count); // резервируем
P> резервируем. кол-во элементов, но зачем резервируем, куда и что вообще это значит?)
Выделяем память под элементы. Создаём массив.
И в этот массив будем читать файл.
Думаю, есть смысл сперва прочитать про vector и т.п., а только потом уже бросаться кодить.
Иначе будешь ловить один access violation за другим.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Psihadelic, Вы писали:
P>>Спасибо большое! Конечно не всё понял, но спасибо! Про сериализацию почитал на МСДН, теперь хоть знаю что это такое, но в суть не очень вник, инфы было мало, а читать форум мне пока ещё сложно (не тот уровень знаний).
P>>Не знаю, что такое POD-тип, но у меня students это простой класс.
К>Гугл в помощь.
К>Если коротко, это такой тип, объекты которого можно копировать побайтово. Plain Old Data — "старые добрые простые данные".
К>
P>>Хочу задать парочку вопросов:
P>>1) что такое size_t ?
К>Стандартный тип для представления размеров данных.
К>Аналог unsigned int, грубо говоря. (Тонкости возникают на 64-битных платформах LLP64 и LP64, где sizeof(int)=4, sizeof(size_t)=8).
P>>2) out.write((const char*)&count, sizeof(count)); // сохраняем количество
P>> зачем нам сохранять количество элементов и можно ли написать это одной строкой?
К>Затем, что мы же должны оставить потомкам сведения: сколько элементов в массиве.
К>У нас есть 3 стратегии: префиксная, инфиксная, суффиксная.
К>Префиксная — записать "сколько", а потом элементы.
К>Суффиксная — записать элементы и в конце особый завершающий элемент. Например, студента с пустым именем.
К>Инфиксная — записать последовательность, в которой чередуются маркеры (продолжение/конец) и элементы: что-то вроде "+", элемент, "+", элемент, "+", элемент, "-".
К>Соответственно, чтение
К>Префиксная — прочитать "сколько", затем прочитать столько элементов подряд.
К>Суффиксная — читать элементы поштучно и проверять, не является ли очередной признаком конца.
К>Инфиксная — читать маркеры и элементы поштучно; когда прочитан маркер конца, не пытаться прочесть следующий элемент (его там нет).
P>>3) зачем читать количество? in.read((char*)&count, sizeof(count)); // читаем количество
К>Чтобы узнать, сколько элементов следует за ним в файле.
К>Только в том случае, если размер элемента в файле постоянный, и ничего иного в файле нет, — можно взять размер файла и поделить на размер элемента.
P>>4) MasSt.resize(count); // резервируем
P>> резервируем. кол-во элементов, но зачем резервируем, куда и что вообще это значит?)
К>Выделяем память под элементы. Создаём массив.
К>И в этот массив будем читать файл.
К>Думаю, есть смысл сперва прочитать про vector и т.п., а только потом уже бросаться кодить.
К>Иначе будешь ловить один access violation за другим.
Да вы не думайте, что я на форум лезу, а читать мне лень, всё я читаю, но из книг бывает невозможно почерпнуть всё. Может книги у меня не те (Шилдт, Либерти, Дейтлы). Спасибо больше за помощь! Я студент, я только учусь)
Здравствуйте, Psihadelic, Вы писали:
К>>Думаю, есть смысл сперва прочитать про vector и т.п., а только потом уже бросаться кодить.
К>>Иначе будешь ловить один access violation за другим.
P>Да вы не думайте, что я на форум лезу, а читать мне лень, всё я читаю, но из книг бывает невозможно почерпнуть всё. Может книги у меня не те (Шилдт, Либерти, Дейтлы). Спасибо больше за помощь! Я студент, я только учусь)
Я очень хорошо понимаю. Просто на форуме рассматриваются частные вопросы, а в книгах есть возможность получить связную картину. Про сериализацию, про устройство контейнеров, про "модели" объектов (Default Constructible, Copy Constructible, Assignable и т.п.) — это вопрос даже не одной лекции. А это всё — базовые вопросы, к которым мы подступились в этой дискуссии.
Что касается книг, то Шилдт — скорее всего, "не та" книга. Его уже столько раз пропесочивали и за очепятки, и за смысловые ошибки.
Дейтелы. затруднюсь сказать. Читал очень давно, и это была лучшая книга на тот момент.
Вот неплохо бы почитать Герба Саттера. "Эффективная" серия по С++.
Если хватит сил и понимания, то — книги Страуструпа (автор языка) и Степанова (автор STL). Хотя, скорее, это на перспективу.
Чорт! Тут можно вообще учебный план выстраивать.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Psihadelic, Вы писали:
К>>>Думаю, есть смысл сперва прочитать про vector и т.п., а только потом уже бросаться кодить.
К>>>Иначе будешь ловить один access violation за другим.
P>>Да вы не думайте, что я на форум лезу, а читать мне лень, всё я читаю, но из книг бывает невозможно почерпнуть всё. Может книги у меня не те (Шилдт, Либерти, Дейтлы). Спасибо больше за помощь! Я студент, я только учусь)
К>Я очень хорошо понимаю. Просто на форуме рассматриваются частные вопросы, а в книгах есть возможность получить связную картину. Про сериализацию, про устройство контейнеров, про "модели" объектов (Default Constructible, Copy Constructible, Assignable и т.п.) — это вопрос даже не одной лекции. А это всё — базовые вопросы, к которым мы подступились в этой дискуссии.
К>Что касается книг, то Шилдт — скорее всего, "не та" книга. Его уже столько раз пропесочивали и за очепятки, и за смысловые ошибки.
К>Дейтелы. затруднюсь сказать. Читал очень давно, и это была лучшая книга на тот момент.
К>Вот неплохо бы почитать Герба Саттера. "Эффективная" серия по С++.
К>Если хватит сил и понимания, то — книги Страуструпа (автор языка) и Степанова (автор STL). Хотя, скорее, это на перспективу.
К>Чорт! Тут можно вообще учебный план выстраивать.
Спасибо большое за то, что посоветовали книги! Герба Саттера. "Эффективная" серия по С++ я не нашёл, но скачал другую его книгу, очень хорошая и интересная, но о векторах я там не нашёл.
Пока код добавления в файл и чтения из файла, подпишу где выскакивает ошибка, а ошибка следующая: Expression:: vector subscript out of range
For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts
Добавление в файл:
Чтение из файла:
Ошибку выдаёт лишь в том случае, если читать сразу после запуска программы, если же после запуска выполнить добавление в файл, и не закрывая читать, то оно работает, но не так, как нужно (читает какую-то фигню, логики в том чтении не вижу, может прочитать весь файл, а в следующий раз только половину).
Здравствуйте, Psihadelic, Вы писали:
P>Чтение из файла:
P>
P>Ошибку выдаёт лишь в том случае, если читать сразу после запуска программы, если же после запуска выполнить добавление в файл, и не закрывая читать, то оно работает, но не так, как нужно (читает какую-то фигню, логики в том чтении не вижу, может прочитать весь файл, а в следующий раз только половину).
Здравствуйте, Psihadelic, Вы писали:
P>Спасибо большое за то, что посоветовали книги! Герба Саттера. "Эффективная" серия по С++ я не нашёл, но скачал другую его книгу, очень хорошая и интересная, но о векторах я там не нашёл.
Для чего в мире есть дебаггер, э?
P>Добавление в файл:
P>[ccode]
P> ofstream out("test", ios::app | ios::binary | ios::out);
P> if(!out)
P> <
P> cout << "не удаётся открыть заданый файл" << endl;
return; // <-- иначе мы поедем дальше с неоткрытым файлом
P> >
P> students _obj; // студенты это класс, там методов нет, только переменные
P> init(_obj); // инициализация объекта
P> MasSt.push_back(_obj); // добавляю в свой вектор объект студентов, а далее по тому, что мне посоветовали на форуме:
P> int count = MasSt.size();
P> out.write((const char*)&count, sizeof(count));
P> out.write((char*) &MasSt[0], count * sizeof (students));
P> out.close();
P>[/code]
P>Чтение из файла:
P>
P>Ошибку выдаёт лишь в том случае, если читать сразу после запуска программы, если же после запуска выполнить добавление в файл, и не закрывая читать, то оно работает, но не так, как нужно (читает какую-то фигню, логики в том чтении не вижу, может прочитать весь файл, а в следующий раз только половину).
Читайте также: