Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
Pray
0 / 0 / 1
Регистрация: 08.05.2016
Сообщений: 31
1

Запись класса в двоичный файл

12.09.2016, 05:25. Просмотров 2037. Ответов 13
Метки нет (Все метки)

Добрый день дорогие друзья.
никак не могу осуществить запись\чтение класса в двоичный файл. в принципе если говорить о записи, то на сколько позволяют судить мои скромные познания запись я произвожу, но когда пытаюсь прочитать ничего не выходит - получаю иероглиф. не мог бы кто поделится примером.

мой класс выглядит так:
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
class DATES {
    private:
        int day, month, year;
        char word; 
    public:
        void getDate () {
            cout << day << "." << month << "." << year << endl;
        }
        bool setDate () {
            cout << "day ";
            cin >> day;
            cout << "month ";
            cin >> month;
            cout << "year ";
            cin >> year;
            if (check (day, month, year) != 0) {
                cout << "wrong date";
                return false;
            }
            return true;
        }
        bool check (int day, int month, int year) {
            if (day < 1 && day > 31){
                return false;
            } else if (month < 1 && month > 12) {
                return false;
            } else if (year > 2016) {
                return false;
            }
            return true;
        }
};
0
Лучшие ответы (1)
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.09.2016, 05:25
Ответы с готовыми решениями:

Запись в двоичный файл
Нужно в двоичный файл 80-символьный заголовок и 4 байтовое беззнаковое целое число. //.. ...

Запись массива в двоичный файл
Здравствуйте. Нужно организовать заполнение двоичного файла случайными целыми числами в интервале ....

Запись в двоичный файл портит данные
Есть файл, в который в двоичном формате записываются структуры. Нужен метод, который будет...

Запись двумерного вектора в двоичный файл
Предположим, что у меня есть двумерный вектор. Как записать его в бинарник? ...

Шаблон класса для записи данных в двоичный файл
Доброго времени суток! Нужно организовать шаблон для записи данных в двоичный файл. Но мне...

13
MansMI
1457 / 1165 / 551
Регистрация: 08.01.2012
Сообщений: 4,509
12.09.2016, 07:20 2
sizeof(DATES) сколько показывает?
0
zss
Модератор
Эксперт С++
8784 / 7676 / 4745
Регистрация: 18.12.2011
Сообщений: 20,429
Завершенные тесты: 1
12.09.2016, 08:09 3
Приведите Ваш код чтения/записи в файл?
0
Pray
0 / 0 / 1
Регистрация: 08.05.2016
Сообщений: 31
12.09.2016, 10:25  [ТС] 4
MansMI, показывает 16

zss, привожу
C++
1
2
3
4
fstream  fbin("1.bin", ios::binary | ios::in | ios::out);
    fbin.write((char*)&dateWrite, sizeof (dateWrite));
    fbin.read((char*)&dateRead, sizeof(dateRead));
    dateRead.getDate();
0
12.09.2016, 10:25
Avazart
Эксперт С++
7965 / 5787 / 571
Регистрация: 10.12.2010
Сообщений: 26,607
Записей в блоге: 17
12.09.2016, 11:15 5
Pray, Приведи весь код в месте с main
0
Pray
0 / 0 / 1
Регистрация: 08.05.2016
Сообщений: 31
13.09.2016, 02:07  [ТС] 6
Avazart, привожу
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
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
 
using namespace std;
 
class DATES {
    private:
        int day, month, year;
        char word; 
    public:
        void getDate () {
            cout << day << "." << month << "." << year << endl;
        }
        bool setDate () {
            cout << "day ";
            cin >> day;
            cout << "month ";
            cin >> month;
            cout << "year ";
            cin >> year;
            if (check (day, month, year) != 0) {
                cout << "wrong date";
                //return false;
            }
            return true;
        }
        bool check (int day, int month, int year) {
            if (day < 1 && day > 31){
                return false;
            } else if (month < 1 && month > 12) {
                return false;
            } else if (year > 2016) {
                return false;
            }
            return true;
        }
};
 
int main () {
    DATES dateWrite, dateRead;
    if (dateWrite.setDate()){
    dateWrite.getDate();
    }
    //cout << "size " << sizeof(DATES) << endl;
    
    char filename[81];
        
    fstream  fbin("1.bin", ios::binary | ios::in | ios::out);
    fbin.write((char*)&dateWrite, sizeof (dateWrite));
    fbin.read((char*)&dateRead, sizeof(dateRead));
    dateRead.getDate();
    
    return 0;
}
0
nd2
3099 / 2593 / 1134
Регистрация: 29.01.2016
Сообщений: 8,690
13.09.2016, 02:46 7
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    fstream  fbin("1.bin", ios::binary | ios::out);
    if (fbin)
    {
        fbin.write((char*)&dateWrite, sizeof (dateWrite));
        fbin.close();
        fbin.open("1.bin", ios::in | ios::binary);
        if (fbin)
        {
            fbin.read((char*)&dateRead, sizeof(dateRead));
            dateRead.getDate();
            fbin.close();
        }
        else
            cout << "Error opening file for reading!" << endl;
    }
    else
        cout << "Error opening file for writing!" << endl;
0
Avazart
Эксперт С++
7965 / 5787 / 571
Регистрация: 10.12.2010
Сообщений: 26,607
Записей в блоге: 17
13.09.2016, 11:47 8
C++
1
DATES dateWrite;
C++
1
fbin.write((char*)&dateWrite, sizeof (dateWrite));
Нельзя так делать с классами. Так можно поступать только со POD -структурами

Можно создать дополнительный метод, в котором почленно записывать данные.
Но вообще лучше писать не в бинарном виде а в каком нибудь текстовом формате типа xml или json.
К примеру удобно использовать boost::serialization
0
nd2
3099 / 2593 / 1134
Регистрация: 29.01.2016
Сообщений: 8,690
13.09.2016, 13:41 9
Цитата Сообщение от Avazart Посмотреть сообщение
Нельзя так делать с классами.
С чего бы это? С его классом, так, как раз, можно делать.

Добавлено через 2 минуты
Его ошибка была в том, что вот так файл не создастся:
Цитата Сообщение от Pray Посмотреть сообщение
C++
1
fstream *fbin("1.bin", ios::binary | ios::in | ios::out);
И переход от записи к чтению так просто не делается.
0
Avazart
Эксперт С++
7965 / 5787 / 571
Регистрация: 10.12.2010
Сообщений: 26,607
Записей в блоге: 17
13.09.2016, 14:28 10
Цитата Сообщение от nd2 Посмотреть сообщение
С чего бы это? С его классом, так, как раз, можно делать.
С того что не стоит так делать, всегда подобный класс может стать не POD, всегда нужно об этом думать.
Кроме того есть такая штука как выравнивание полей в структурах, чего лучше избегать и записывать почленно поля.
0
Pray
0 / 0 / 1
Регистрация: 08.05.2016
Сообщений: 31
13.09.2016, 15:36  [ТС] 11
Avazart, а можешь дать какие-нибудь учебные материалы или примеры как именно поступить в этом случае. на сколько я понял код представленный nd2 работает, но в некоторых случаях может привести к потере данных. Хотелось бы понять в каких и как этого избегать. Заранее спасибо вам обоим.

З.ы. текстовые и прочие форматы, это конечно замечательно, практично и удобно, но я ограничен заданием и оно предписывает именно двоичное хранение.
0
nd2
3099 / 2593 / 1134
Регистрация: 29.01.2016
Сообщений: 8,690
13.09.2016, 15:42 12
Цитата Сообщение от Avazart Посмотреть сообщение
всегда подобный класс может стать не POD, всегда нужно об этом думать.
Цитата Сообщение от Avazart Посмотреть сообщение
Так можно поступать только со POD -структурами
А POD-структура не может стать не POD?
Цитата Сообщение от Avazart Посмотреть сообщение
Так можно поступать только со POD -структурами
Цитата Сообщение от Avazart Посмотреть сообщение
Кроме того есть такая штука как выравнивание полей в структурах
А на POD-структуры это не распространяется?
0
Avazart
Эксперт С++
7965 / 5787 / 571
Регистрация: 10.12.2010
Сообщений: 26,607
Записей в блоге: 17
13.09.2016, 15:50 13
Лучший ответ Сообщение было отмечено Pray как решение

Решение

Примерно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Date
{
    private:
        int day, month, year;
        char word; 
    public:
       // ...
       std::ostream& writeToBinStream(std::ostream& stream)
       {
            stream.write((char*)&day, sizeof(day));
            stream.write((char*)&month, sizeof(month));
            // ...
            return stream;
       } 
 
      std::istream& readFromBinStream(std::istream& stream)
      {
            stream.read((char*)&day, sizeof(day));
            stream.read((char*)&month, sizeof(month));
            // ...
            return stream;
      } 
}
C++
1
2
3
std::ifstream  fbin("1.bin", ios::binary);
Date d;
d.readFromBinStream(fbin);
Можно также ф-ции сделать дружественными.

Цитата Сообщение от nd2 Посмотреть сообщение
А POD-структура не может стать не POD?
Тут не структура, а класс по своей сути, в и вдруг мы заходим добавить конструктор или вирт.деструктор.
Цитата Сообщение от nd2 Посмотреть сообщение
А на POD-структуры это не распространяется?
Распространяется, поэтому лучше писать/читать почленно.
И еще не плохо бы проверять размеры типов(при компиляции), или же использовать типы с гарантированным размеров(на разных платформах)
2
nd2
3099 / 2593 / 1134
Регистрация: 29.01.2016
Сообщений: 8,690
13.09.2016, 16:01 14
Цитата Сообщение от Pray Посмотреть сообщение
Хотелось бы понять в каких и как этого избегать.
В каких к ошибкам приводит, можешь здесь почитать:
Запись и чтение структуры с файла
Код из "Р.Лафоре. ООП в С++"
Запись и чтение объектов разных классов в один файл
Запись и извлечение данных в несколько запусков программы
Не могу найти ошибку. Запись/чтение из файла
Насчёт проблем с выравниванием:
https://habrahabr.ru/post/142662/
http://www.kalinin.ru/programming/cpp/31_07_00.shtml
2
13.09.2016, 16:01
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.09.2016, 16:01

Запись класса в файл
Доброго времени суток! Вот появился тупик, есть базовый класс и производные классы class Figure{...

Запись класса в файл
Приветствую. Я хочу записать битовую форму класса, но столкнулся с делемой. Насколько мне...

Запись класса в bin файл
Есть класс, одно поле должно быть текстовое, в моем классе model. Данные беруться из StringGrid,...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.