Запись ОБЪЕКТА КЛАССА в файл с++. Чтение объекта из файла c++ Для начинающих. Урок
HTML-код
- Опубликовано: 2 дек 2017
- Cамый лучший способ сказать "спасибо" - поставить лайк и и поделиться уроком с друзьями. Это очень мотивирует создавать полезные уроки =)
Работа с файлами с++. Запись в файл. c++ ofstream. Изучение С++ для начинающих. Урок #115
goo.gl/b7bzup
Работа с файлами с++. Чтение из файла с++ ifstream. Изучение С++ для начинающих. Урок #116
goo.gl/DRoSXS
Если вам нравятся мои уроки, вы хотите поддержать меня и развитие канала, то можете сделать это тут! =)
www.donationalerts.ru/r/simple...
или тут
/ simplecode
Уроки по программированию
Наша группа ВК smplcode
Подписывайтесь на канал / @simplecodeit
*Cамый лучший способ сказать "спасибо" - поставить лайк и и поделиться уроком с друзьями. Это очень мотивирует создавать полезные уроки =)*
Где ссылки на сырцы? по мойму это не прозвучало, что вы по сути изменяете один обьект а не создайте три. ихмо это важно.
Для чего писать ofstream fout; и ofstream::app если и fstream... работает? Ну лично у меня
@@game_cx урок fstream следующий в плейлисте
Огонь!!! Давно искала информацию по сохранению объектов с нормальными разъяснениями. Спасибо большое, наконец сдвинулась с мертвой точки!
ОЧЕНЬ ВАЖНО:
Способ рабочий только для простейший структур. Если есть хоть одно поле string в структуре, работать не будет. Можно конечно сделать вместо string массив из char, но тогда все преимущества строк пропадают.
Самый полезный комментарий
А каким образом это можно преодолеть? Есть ли какие-то другие способы сохранить объект в класс или нужно с нуля писать методы сохранения?
@@calamitydeadshot3143 почитайте что такое JSON или XML
Проблема в том, что в файл сохраняется не поле строчки, а указатель на поле строчки. Естественно, при считывании по том адресу уже этой строчки возможно и нет.
@@vladyslavkryvoruchko о, получается, проблема при наличии любых данных в куче, а не только string. Сохраняются адреса, но не сами данные. Теперь надо думать, как сливать данные в файл из памяти.
Спасибо за разъяснение.
Благослови тебя Господь. Благодарю за уроки!)
бога нет
@@endlessvd по любому "создатель" непременно существует.
@@AsdfgAsdfg12363 ну значит ты открыл только что физику, в частности теорию относительности и квантовую механику. Их действительно можно назвать нашими создателями, а все остальное ерунда
@@endlessvd не будь душнилой, задрот
#работасфайлами #ofstream #ifstream #SimpleCode #урокипрограммирования
Этот урок прям вообще супер, спасибо большое, очень интересно!!!
Это невероятно, огромное спасибо за это видео, я раньше всё сохранял в текст и каждый раз делал кучу лишних преобразований, теперь попробую поэкспериментировать с этим и запомню.
Видео не просто полезно, а очень и очень полезно! Огромное спасибо за труд!
Очередное спасибо и лайк. Очень нравятся Ваши уроки. Только не останавливайтесь!
Спасибо Вам . Все понятно и доходчиво. Вы как всегда СУПЕР.
Спасибо за бесценный труд!)
Спасибо, очень познавательный урок!
Огромное спасибо!
О! Класс!!! А я на Вас подписан! Даже и не подозревал, что Вы увлекаетесь программированием! )))
Действительно очень полезные видео. Так держать!
спасибо вам большое Из всего ютуба ваши уроки смотрю с большим энтузиазмом и досматриваю до конца 👩💻👍👍👍👍👍👍👍👍👏👏👏👏👏👏👏👏
Спасибо за Урок!
Спасибо вам большое за уроки , вы очень сильно мне помогли вы изучении и в практики написании собственных и учебных проектов на c++!
Сергей, спасибо за урок!
Сергей нам нравиться эта тема и нравятся твои уроки!
Думал будет перегрузка
А что это, приведение к типу?
@@alexs7931 Угу. Получаем адрес объекта и приводим указатель на объект к указателю на байты (char).
Сергей, спасибо!
Спасибо за урок!
Сложно. Но я разберусь есть цель: сделать прогу которая будет закидывать в массив слова через сортировку прогонять. Через какой ни будь API. И уже потом перевод слова будет через туже сортировку записанный клеить с словом в массиве. В общем то, что нужна инфа ононь!
ГОСПОДИ ЭТО ПРОСТО БОХ !!! СПАСИБО!!!!! УЖЕ ГОЛОВУ СЛОМАЛ НАД ЭТИМ!
lol
Довольно интересная тема))
Огромное спасибо за уроки с классами! И небольшой совет... пользуйтесь другим блокнотом, например notepad++
Лучшие УРОКИ!!!😊😊😊
Спасибо тебе большое !!! Жаль что невыпускаешь контент про плюсы
Спасибо за видео!
спасибо! просто лучший
Хороший урок!
спасибо я добавил еще условие чтобы считывать определенную строчку
Спасибо.
Хорошее видео потому как делать. Если в классе есть виртуальные функции то и есть таблица Виртуальных функций которая также храниться в памяти объекта, твф хранит в себе адреса перехода на виртуальные функции и её изменение при считывании с файла может привести к непредвиденным результатам. Я имею ввиду при чтении неправильных данных из файла найти баг будет очень сложно.
РЕСПЕКТ !!!
Полезный урок
Спасибо огромное!
Пожалуйста!
подскажите, пожалуйста, подойдет ли такой метод для структур?
Да )
Сразу уточню я не смотрел все видео, просмотрев несколько очень понравилось как подается материал. Меня очень интересует как работать с бинарными файлами, как в них записывать, считывать информацию насколько я знаю там есть существенные отличия в сравнении с текстовыми файлами. Также интерестно узнать о возможностях работы с другими приложениями через С++ будут ли такие видео?
Автору огромный респект за видео 👍
А можно ли сделать дополнительные вывод на принтер
Очень полезный урок
Бинарные? Так вот что за .bin файлы, наконец-то я это узнал
Ставлю лайки постоянно т. к. это очень клевые уроки по плюсам. Но год нет почему-то комментов. Или все свалили уже на модный C#...
Дякую!!!
можно использовать reinterpret_cast(&point) место char*(&point)
Огромное СПАСИБО, я бы даже рекламу смотрел!
Еще бы хотелось бы увидеть видео по записи структур и вывода.
Ставь рекламу!!!Пусть будет для тебя еще одной мотивацией=)
ну или ты поставил, а она у меня пропала и я не могу ее смотреть.
топчик
Храни тебя Господь!!! Спасибо большое 🙏🙏🙏
спасибо
в случае работы с виртуальными методами, нужно сделать немного иначе:
Base *deriveClass=new Derive(); //создаем указатель на клас-наследника, через указатель на базовый клас
char* charArray = static_cast(dynamic_cast(deriveClass)); // так выглядит преобразование полиморфического класа в масив чаров с сохранением свойств полиморфизма
ofstream.write(charArray, sizeof(Derive)); // записываем данные.
Точно так же проходит и считывание. Сишный стиль преобразования типов это плюсовый static_cast, а он не учитывает свойств полиморфизма, т.к. это фича плюсов
Спасибо
Спасибо)
5:40 приводить к char'y мы будем ссылку на объект Point
Не ссылку, а указатель. & это операция взятия адреса
отлично
Like!
Очень все супер, один вопрос, объекты с переменными типа string и int выводит с ошибкой, просит отладить, что можно поправить???
👌👌👌👌
Сергей, а почему вы не пользуетесь списком инициализации? Он ведь быстрее работает
Выдержка с MSDN
используются только в языке C++. Эти операторы позволяют устранить неоднозначность и возможности допустить ошибку, которые характеры для приведения типов в стиле языка C. Эти операторы перечислены ниже.
dynamic_cast используется для преобразования полиморфных типов.
static_cast Используется для преобразования неполиморфных типов.
const_cast Используется для удаления constvolatileатрибутов, а также __unaligned атрибутов.
reinterpret_cast Используется для простого переосмысления битов.
safe_cast используется в C++/CLI для создания проверяемой MSIL.
Можно следующий урок про файловый ввод/вывод? Для олимпиады очень нужно пожалуйста.
Если я всё правильно понял, это же было в двух прошлых видео? Разве нет?
@@user-pk3tq5vk9b Да, Илья, ты правильно понял...
@@user-or1hy4xz8u оба ответили друг другу через два года
@@user-hl1bh9hv3u лучше позже, чем никогда)))
Добрый вечер!Напишите пожалуйста как можно вводить данные не закрывая консоль?(В вашей программе идет ввод и консоль закрывает,затем нужно второй раз запускать программу для повторного ввода)
10/10
Кстати, преобразование (char*)&point можно сделать в стиле С++, reinterpret_cast(&point). А вот через static_cast не работает.
Ну static_cast же работает напрямую с переменной, а не через ее псевдоним или адрес. Это лишь моя догадка, поэтому если неверно, поправьте)
👍🏿👍🏿👍🏿
кстати можно зашифровать сообщение какое-нибудь в виде бинарного кода в блокноте)
это тема)
Спасибо большое за видео!
Объясните пожалуйста, почему при явном приведении использовался указатель? (char*) ?
Потому что метод read работает только с указателями на char. Но поскольку любой указатель содержит в себе лишь адрес объекта в памяти, его можно явно привести к указателю на любой другой тип. Неважно, находится ли обьект такого типа по данному адресу или нет. Дальнейшая работа с таким указателем остаётся на совести программиста
Все хорошо! Но, нужено больше примеров метов, организации данных. Чтоб случайно не изобрести велосипед 😊.
велосипеды изобретать полезно....
спасибо за урок) У меня опрос: если я не закрою файл функцией fin.close(), это будет утечка динамической памяти, или я просто забуду прекратить работу с файлом?
вопрос*
утечки памяти не будет, будет не доступен ресурс для других приложений(тхт файл). типо как в библиотеке, ты взял почитать книгу, прочел ее, но не вернул обратно, и для других читателей она не доступна.
файл недоступен, и прога слетает или в лучшем случае ошибку дает. оно тебе надо?
Не совсем понимаю. Если навести на метод read, то там будет тип возвращаемого значения istream, а не bool. Тогда почему его можно использовать в while и в if?
Здравствуйте,спасибо большое за ваши видео,желаю вам успехов в вашем не легком деле. Не могли бы вы поправить нумерацию уроков в первых 15-ти,чтобы изучать их по порядку.
Пожалуйста, а что не так с нумерацией? Там всё по прядку.
Я с самого первого урока. С нуммерацией не заметил ничего крамольного, проглотил все на одном дыхании, за один день. Сиди и учи, не выпендривайся! :)
@@TheWladberlin ты ответил через 2 года, а через это время уже нумерацию он изменил
Данный способ не сработал для меня, когда я использовал его для наследника абстрактного класса. После записи из файла в объект, при попытке вызова виртуальной функции, которая была переписана в наследнике, мне выдает ошибку доступа к памяти.
хм, у меня всё нормально работает, если я правильно понял, что сохранялся и читался один и тот же класс. Если же классы разные, то конечно будет ошибка, потому что размеры объектов у этих классов разные.
в случае работы с виртуальными методами, нужно сделать немного иначе:
Base *deriveClass=new Derive(); //создаем указатель на клас-наследника, через указатель на базовый клас
char* charArray = static_cast(dynamic_cast(deriveClass)); // так выглядит преобразование полиморфического класа в масив чаров с сохранением свойств полиморфизма
ofstream.write(charArray, sizeof(Derive)); // записываем данные.
Точно так же проходит и считывание. Сишный стиль преобразования типов это плюсовый static_cast, а он не учитывает свойств полиморфизма, т.к. это фича плюсов
Можно вопрос: а если у нас структура работать будет также?
up
up
ничего непонятно, но очень интересно.
А что делать если при считки с файла, оно считывает до последнего елемента,причем считывает до последней характеристики и потом на ней же просто кидает segmentation fault?
Друзья интересующиеся программированием так далеко еще не заходили )))
Как записывать класс с полем string?
я так понимаю что со стринг тут не получиться, тк стринг имеет всегда разный обьем в битах, а тобиж если хочешь записать строку, то нужно заводить масив чаров, к примеру массив содержащий 255 символов, и кидать туда свою строку которая по обьему будет меньше 255 символов, и опять же строку брать нужно не из класса записываемого, а тобиж реализация класса с записью и использованием стринг с этим методом под вопросом. Хотя можно использовать искуственый метод который приведет все стринги к опр кол ву символов и запишет, и метод который уберет лишние символы при считывании. Тогда стринг будет одной длинны по битам
String s; s.c_str()возвращает указатель на char*, который и записываете
@@user-cs3dq1st7n тут проблема в другом, фактически в классе хранится не строка, а её управляющий элемент (длинна, указатель на динамический массив). её надо записывать и читать отдельно, как в прочем и все динамические массивы. а с указателями вообще беда. ты его записал, прочитал, а в другом сеансе он невалиден (
Добрый день. Спасибо за урок. Если в классе динамически выделяется память, после чтения объекта данного класса с файла, возникает ошибка при освобождении памяти. Могли бы Вы рассказать как обходить такие моменты?
Когда набирал пример по вашему уроку, подобная проблема возникала даже с полем класса типа string.
никогда так писать нельзя. это пример для обучения. гуглите сериализацию, это отдельная задача в программировании
Как бороться с Eof если данных много:?
Вот это конечно...
сохраняются ли методы класса или же только поля?
Как ты собираешься записать методы класса в файл? Методы это функции для работы с обьектами класса. Обьект не содержит функции, он содержит только данные(поля).
@@feewre я уже давно разобрался с этим вопросом, понял уже, что только поля сохраняются
Передача экземпляров класса , который принимает числа -работает. А что делать если хочешь передавать словп/string ???Подскажите кто нибудь.
а зачем использовать Write если можно в самой функции print записывать значение в Фаил?
Как записывать и считывать объекты, у которых есть полe - указатель на динамическую память?
уроки очень интересные, но я перешёл на книги, и изучал уже по ним, и у меня вопрос возник, есть exe файл, его нужно побайтово считать и записать в массив, после чего когда пользователь нажмёт на кнопку, то файл должен из массива снова собраться в exe и запуститься, я так понимаю, что это как то можно через fstream сделать, но как я вообще не представляю, есть тут знатоки, скиньте ссылочку, или объясните в кратце принцип, а то поиск в гугле дал мутные ответы
Пожалуйста, объясните логику преобразования в этой строке: (char*)&point
char* - указатель, содержит адрес памяти.
&point - не ссылка, как сказал уважаемый Сергей, видимо по ошибке, а тоже адрес объекта.
(char*)&point обязывает рассматривать адрес объекта point как адрес на область памяти типа char.
Ведь функция write принимает именно указатель на char
а можно вот так: write(reinterpret_cast(&o), sizeof(o));
Можно. Один хер, программа у всех вылетает после отработки
Разве на не нужно поместить .close(),в блок else, то есть, если файл не открылся, то зачем его закрывать, и не вызовет ли это ошибки?
у меня ошибка Ошибка C2039 write: не является членом "std::basic_ifstream" Project1 c:\c++\project1\project1\main.cpp 39
1:16 - Есть способ, с помощью которого мы можем не работать. Ага, так и запишем )
Для записи и для чтения намного удобнее использовать отдельные функции с входными параметрами path и point. Через ссылки сделал. Может кому-то поможет:
void fileOpenWrite(string &path, Point &point)
{
ofstream fout;
fout.open(path, ofstream::app);
if (fout.is_open()) {
cout
А как мі понимаем, что в fin.read() нужно считать sizeof(Point) именно тот, который нам нужен?
sizeof(point) всегда один и тот же, если там нет полей string.
Это же сериализация?
никто не подскажет почему после чтения файла в структуру, массив структуры больше не хочет менять свой размер. к примеру,у меня телефонная книга созданная массивом струкруры,пользователь добавляются и удаляются отлично когда работаешь с клавиатуры,но когда заполнил свою струкутру из файла, уже не возможно ни добавить пользователя ни удалить его
у меня там к прошлому уроку
Конечно спасибо за урок! Но у меня осталось очень много вопросов. Сдаётся мне такое ощущение, что эту тему во круг функций: fout.write((char*)&point, sizeof(Point)); и fin.read((char*)&pnt, sizeof(Point)); Вы осветили очень, и очень поверхностно. Каким образом функция понимает, что именно и в каком количестве сохранить и прочитать? Ка сохранять сложные, унаследованные классы, с вложенными классами как быть? Как сохранить массив экземпляров класса? Поштучно, или есть варианты, сразу пачкой? Эти функции нормально работают, если говорить о нескольких строках записи. А попробуйте в цикле записать 10тыс. строк, и прочитать их. Количество записанных и количество прочитанных строк сильно разнятся, даже в таком простом варианте, как в Вашем примере.
Лайки авансом, в надежде, что на эти вопросы я найду ответы в Ваших следующих видео.
сам гугли находи и экспериментируй
неужто всё разжевывать нужно?
@@lacklacktriplehack4174 На давность комминта не смотришь чтоль? Уже всё давно за гуглил и нашёл. =)
@@BrownAleks это на будущее другим челикам
что сенсей не обязан разжевывать всё от корки до корки
А в чистом виде, обект вписать реально?
Что значит в чистом виде? Если Вы имеете в виду так, чтобы можно было открыть файл и прочесть данные, то можно просто выводить текстом поля объекта (это материалы прошлых уроков)
Почему это не работает для объектов string выдаёт ошибку доступа на выходе из самой программы
вроде бы со стрингом и динамической памятью нельзя работать.
Alexey Profit если только стринг сам использует динамическую память, сам я в коде не выделял 🤷🏿♂️
Как я понял string использует динамический массив чаров. При вытаскивании объекта из файла методом read, создается не новый объект, а еще один указатель на старый объект, поэтому на выходе из программы чистится одна и та же область динамической памяти дважды и происходит утечка. Я для себя решил эту проблему так:
string str("sss");
ofstream infile;
infile.open("text.txt");
if (!infile.is_open()) cout
А если в файл записать вообще рандомные символы, и потом считать и привести в Point, то у нас выйдет случайная точка!
Это случайно не бинарная сериализация?
нет
как так коментировать как Сергей в видео?!? хелп
Легко.
Комментировать: [Str]+[k]+[c]
Декомменторовать: [Str]+[k]+[u]