С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
0 / 0 / 0
Регистрация: 10.04.2020
Сообщений: 6

Запись и чтение объекта класса в файл

17.04.2020, 22:37. Показов 2203. Ответов 17

Студворк — интернет-сервис помощи студентам
Доброго времени суток. Хочу разобраться с записью и чтением объекта класса в файл. Написал элементарную программу, но при чтении программа вылетает при выходе из фунции main

Сама ошибка - Вызвано исключение: нарушение доступа для чтения. _Pnext было 0xF4D3FC


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
  #include <iostream>
 #include <string>
 #include <fstream>
 using namespace std;
 
class file_test
{
    string str1;
    string str2;
    string str3;
    int a;
    int b;
public:
    file_test() 
    {
        str1 = "0";
        str2 = "0";
        str3 = "0";
        a = 0;
        b = 0;
    };
    file_test(string str1, string str2, string str3, int a, int b)
    {
        this->str1 = str1;
        this->str2 = str2;
        this->str3 = str3;
        this->a = a;
        this->b = b;
    };
    ~file_test() {};
};
 
 
int main()
{
    /*file_test file("d","d","d",1,1);
    ofstream fout;
    fout.open("myfile.txt");
    fout.write((char*)&file, sizeof(file_test));
    fout.close();*/
 
 
    ifstream fin;
    file_test file;
    fin.open("myfile.txt");
    fin.read((char*)&file, sizeof(file_test));
    fin.close();
    return 0;
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.04.2020, 22:37
Ответы с готовыми решениями:

Запись и чтение объекта класса в файл и из файла
У меня есть std::list состоящий из объектов типа Person это база о людях. Нужно реализовать два метода, запись всей базы в файл, и...

Запись объекта класса в файл и чтение из файла (Вызвано необработанное исключение: нарушение доступа для чтения)
Доброго времени суток. Вообщем-то есть некий класс Weapons: class Weapons { public: void AddWeapon(string nam, int ispkab, string...

Запись и чтение объекта в файл
у меня есть класс A,как мне записать в файл несколько объектов этого класса а потом их считать?

17
Гвоздь Задиров
 Аватар для Folian
1718 / 1117 / 337
Регистрация: 25.01.2019
Сообщений: 2,940
18.04.2020, 00:54
Цитата Сообщение от Marliken Посмотреть сообщение
C++
1
2
3
string str1;
    string str2;
    string str3;
Это уже не POD,
Цитата Сообщение от Marliken Посмотреть сообщение
C++
1
sizeof(file_test)
так не выйдет
0
0 / 0 / 0
Регистрация: 10.04.2020
Сообщений: 6
18.04.2020, 00:59  [ТС]
Цитата Сообщение от Folian Посмотреть сообщение
Это уже не POD,
так не выйдет
А как это исправить? И что такое POD?
0
Гвоздь Задиров
 Аватар для Folian
1718 / 1117 / 337
Регистрация: 25.01.2019
Сообщений: 2,940
18.04.2020, 01:08
Начну с конца:
Цитата Сообщение от Marliken Посмотреть сообщение
И что такое POD?
Простая структура данных (англ. plain old data, POD) — в современных языках программирования высокого уровня тип данных, имеющий жёстко определённое расположение полей в памяти, не требующий ограничения доступа и автоматического управления.
Это было в первой ссылке гугла по википедии. Наверное там есть и более ясные ответы.
Короче, сам string имеет фиксированый объём как класс, а что ты туда пишешь - под это выделяется память в другом месте. sizeof твой берёт размер string как класса, но ему неведомо что ты там в него написал.

Цитата Сообщение от Marliken Посмотреть сообщение
А как это исправить?
контролируй размер каждого string и записывай/считывай в соответствии с этим контролем.
Накидаю примерчик сейчас, может быть. А может и нет
1
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
18.04.2020, 03:37
Лучший ответ Сообщение было отмечено Marliken как решение

Решение

Цитата Сообщение от Marliken Посмотреть сообщение
А как это исправить?
Не использовать бинарные методы записи/чтения, или заменить std::string на массивы char.
0
 Аватар для sergeydeleu
20 / 9 / 4
Регистрация: 22.01.2015
Сообщений: 186
19.04.2021, 09:01
Добрый день!

При чтении объектов из файла возникает такая ошибка. Что бы это значило?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <string>
#include <fstream>
 
using namespace std;
 
class PhoneBook {
private:
    string tnumber, name;
public:
 
    void SetName(string nm) {
        name = nm;
    }
 
    string GetName() {
        return name;
    }
    void Print() {
        cout << name;
    }
};
 
 
 
 
void main() {
    setlocale(0, "ru");
    string path = "file.txt";
 
 
    //PhoneBook user;
    //user.SetName("Kevin");
    //cout << user.GetName();
 
    //ofstream fout;
    //fout.open(path, ofstream::app);
 
    //if (!fout.is_open()) cout << "Ошибка открытия файла!" << endl;
    //else {
    //  cout << "Файл открыт!";
    //  fout.write((char*)&user, sizeof(PhoneBook));
    //}
    //fout.close();
 
    ifstream fin;
    fin.open(path);
    if (!fin.is_open()) cout << "Ошибка открытия файла!" << endl;
    else {
        cout << "Файл открыт!" << endl;
        PhoneBook read;
        while (fin.read((char*)&read, sizeof(PhoneBook))) {
 
            read.Print();
        }
        
    }
 
    fin.close();
 
}
0
Гвоздь Задиров
 Аватар для Folian
1718 / 1117 / 337
Регистрация: 25.01.2019
Сообщений: 2,940
19.04.2021, 10:32
Цитата Сообщение от sergeydeleu Посмотреть сообщение
fin.read
А не надо для этой штуки открывать файл как ios::binray ?
Цитата Сообщение от sergeydeleu Посмотреть сообщение
fin.read((char*)&read, sizeof(PhoneBook))
Опять же, просто так в не-POD не скопируешь.

Что-то такое попробуй:

C++
1
2
3
4
5
6
7
8
9
        PhoneBook read;
    //  while (fin.read((char*)&read, sizeof(PhoneBook))) {
        std::string temp;
        while(std::getline(fin, temp))
        {
            read.SetName(temp);
            read.Print();
            std::cout << "\n";
        }
Или обязательно через бинарностЬ?
1
 Аватар для sergeydeleu
20 / 9 / 4
Регистрация: 22.01.2015
Сообщений: 186
19.04.2021, 10:42
Цитата Сообщение от Folian Посмотреть сообщение
Или обязательно через бинарностЬ?
Не обязательно.

Code
1
2
3
4
5
6
7
8
PhoneBook read;
        // while (fin.read((char*)&read, sizeof(PhoneBook))) {
        string temp;
        while(getline(fin,temp)){
            read.SetName(temp);
            read.Print();
            cout << endl;
        }
Получилось че-то такое:



Как я понял, этот код считывает из файла строки, а мне надо считывать объекты. Для этого надо учитывать размер объекта!?
0
Гвоздь Задиров
 Аватар для Folian
1718 / 1117 / 337
Регистрация: 25.01.2019
Сообщений: 2,940
19.04.2021, 11:01
Цитата Сообщение от sergeydeleu Посмотреть сообщение
Получилось че-то такое:
Ну, я вижу ты его бинарно записывал - мож там такое и есть.

Бинарно туда-сюда не-POD писать - нужно под каждый такой элемент размер сохранять.
Например, для одной std::string, чтоб понятней было:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
    string path = "f.txt";
 
    std::string str = "sadldlas asklnl ank nkawlklf\n n 23901\n 3nit13i  kaksf ";
 
    ofstream fout;
    fout.open(path, ofstream::binary);
 
    if (!fout.is_open()) cout << "Ошибка открытия файла!" << endl;
    else {
        size_t size = str.size();
        fout.write(reinterpret_cast<char*>(&size), sizeof(size_t)); //сначала пихаем размер
        fout.write(str.data(), size); //потом саму строку из строки(не сам класс, а данные)
    
        fout.close();
    }
 
 
    std::string new_str;
 
    ifstream fin;
    fin.open(path, ofstream::binary);
    if (!fin.is_open()) cout << "Ошибка открытия файла!" << endl;
    else {
 
        size_t size;
        fin.read(reinterpret_cast<char*>(&size), sizeof(size_t)); //читаем размкр
        new_str.resize(size); //выделяем память в новой строке под размер
        fin.read(new_str.data(), size); //читаем в выделенную память из файла size байт
 
        fin.close();
    }
 
    std::cout << new_str;
N.B.: reinterpret_cast - это опасная штука, может где-то найдётся пример более безопасный.

Добавлено через 5 минут
Цитата Сообщение от sergeydeleu Посмотреть сообщение
Не обязательно.
В этом случае проще обойти приватность
Цитата Сообщение от sergeydeleu Посмотреть сообщение
string tnumber, name;
и писать прямо в них, безо всякого гессороя
1
 Аватар для sergeydeleu
20 / 9 / 4
Регистрация: 22.01.2015
Сообщений: 186
19.04.2021, 11:13
0
Гвоздь Задиров
 Аватар для Folian
1718 / 1117 / 337
Регистрация: 25.01.2019
Сообщений: 2,940
19.04.2021, 11:34
sergeydeleu, C++17;

Можно через какой char[] - буфер или ещё что принимать:
C++
1
2
3
4
5
6
7
8
9
10
        size_t size;
        fin.read(reinterpret_cast<char*>(&size), sizeof(size_t)); //читаем размкр
       // new_str.resize(size); //выделяем память в новой строке под размер
        char * buff = new char[size + 1]; // дорогое удовольствие
        buff[size] = '\0';
        fin.read(buff, size); //читаем в выделенную память из файла size байт
 
        new_str = buff;
 
        delete buff;
не проверял.
1
 Аватар для sergeydeleu
20 / 9 / 4
Регистрация: 22.01.2015
Сообщений: 186
19.04.2021, 11:37
Цитата Сообщение от Folian Посмотреть сообщение
не проверял.
Спасибо! Позже проверю!
0
Гвоздь Задиров
 Аватар для Folian
1718 / 1117 / 337
Регистрация: 25.01.2019
Сообщений: 2,940
19.04.2021, 11:40
sergeydeleu, кстати, если у тебя современна VS - поковыряйся в настройках, там по умолчанию C++14 чтоль стоит, поменяй до 17 - так проще будет.
1
 Аватар для sergeydeleu
20 / 9 / 4
Регистрация: 22.01.2015
Сообщений: 186
19.04.2021, 12:34
так проще будет
Спасибо, а можно узнать в чем именно?
0
 Аватар для sergeydeleu
20 / 9 / 4
Регистрация: 22.01.2015
Сообщений: 186
20.04.2021, 07:50
Все работает, спасибо!
0
Гвоздь Задиров
 Аватар для Folian
1718 / 1117 / 337
Регистрация: 25.01.2019
Сообщений: 2,940
20.04.2021, 10:05
Цитата Сообщение от sergeydeleu Посмотреть сообщение
Все работает, спасибо!
Каким способом сделал?
В любом случае, через char * buff там косяк, не delete buff;, а delete [] buff; нада.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
20.04.2021, 10:14
Цитата Сообщение от Folian Посмотреть сообщение
дорогое удовольствие
Можно так (после resize, разумеется):
C++
1
fin.read(&new_str[0], size);
начиная с С++11 это всегда работает как ожидается.
1
 Аватар для sergeydeleu
20 / 9 / 4
Регистрация: 22.01.2015
Сообщений: 186
20.04.2021, 12:29
Каким способом сделал?
Вечером посмотрю.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.04.2021, 12:29
Помогаю со студенческими работами здесь

Сохранение и чтение объекта класса в файл/из файла
Добрый день! Столкнулся с проблемой сохранения объекта класса в файл, и последующего его чтения. Задача такая: имеем vector base, в...

Запись в файл объекта класса
Добрый вечер,предположим есть подобный класс,с полями : const SIZE = 10; class myClass { public: int arr; ...

Запись в файл объекта класса
class Object { private: int myN; std::vector&lt;std::string&gt; myLines; public: Object(); ~Object(); void...

Запись объекта класса в файл
Доброго времени суток! нужно сохранить объект вот такого класса: class Act { public: Act(); Act(string...

Запись объекта класса в файл
Здравствуйте, может кто-нибудь помочь с данным вопросом? Как мне записать в файл строку, которая задается через функцию EnterName()? ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru