1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
1

Вывод в файл и последующее чтение из файла объектов класса

04.05.2012, 01:43. Показов 2565. Ответов 5
Метки нет (Все метки)

Как наиболее правильно и канонично выводить (так чтобы потом ещё и прочитать) объекты классов в файл?
Представим ситуацию:
Есть класс A, от него унаследован класс B и класс C.
Есть функция, которая принимает список объектов А, В и С (вперемешку).
Есть функция, задача которой считать из файла объекты А, В и С (и не перепутать что где) и вернуть список этих объектов.

Как это лучше всего реализовать?
Классы A, B и C пускай будут простенькие. Хоть бы вот такие:
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
class A
{
public:
    A(int _x)
    :x(_x){}
 
    virtual void fun()
    {
        cout<<x<<"\t";
    }
 
private:
    int x;
};
 
class B: public A
{
public:
    B(int _x, int _y)
    :A(_x), y(_y){}
 
    virtual void fun()
    {
        cout<<"B"<<"\t";
        A::fun();
        cout<<y<<endl;
    }
 
private:
    int y;
};
 
class C: public A
{
public:
    C(int _x, char _c)
    :A(_x), c(_c){}
 
    virtual void fun()
    {
        cout<<"C"<<"\t";
        A::fun();
        cout<<c<<endl;
    }
 
private:
    char c;
};
Приведите пример как ЛУЧШЕ ВСЕГО организовать вывод в файл и чтение из файла объектов моих А, В и С.

Добавлено через 31 минуту
Тоесть вся сложность в том что мы заранее не знаем что записано в файл, посему не знаем сколько байт читать и когда у нас один объект закончился, а начался другой ...
Дописал ещё прототипы функций, а также main если кто захочет поэкспериментировать чтобы помочь:
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
class A
{
public:
    A(int _x)
    :x(_x){}
 
    virtual void fun()
    {
        cout<<x<<"\t";
    }
 
private:
    int x;
};
 
class B: public A
{
public:
    B(int _x, int _y)
    :A(_x), y(_y){}
 
    virtual void fun()
    {
        cout<<"B"<<"\t";
        A::fun();
        cout<<y<<endl;
    }
 
private:
    int y;
};
 
class C: public A
{
public:
    C(int _x, char _c)
    :A(_x), c(_c){}
 
    virtual void fun()
    {
        cout<<"C"<<"\t";
        A::fun();
        cout<<c<<endl;
    }
 
private:
    char c;
};
 
struct Block
{
    Block(A* what)
    :obj(what), next(NULL){}
 
    A* obj;
    Block* next;
};
 
void outToFile(Block* list)
{
    while(list)
    {
        
    }
}
 
Block* readFromFile(ofstream& file)
{
 
}
 
 
int main()
{
    A a(1);
    B b(2,2);
    C c(3,'c');
 
    Block* simpleList= new Block(&c);
    simpleList->next= new Block(&b);
    Block* tail= simpleList->next;
    tail->next= new Block(&a);
    outToFile(simpleList);
}
Добавлено через 17 минут
Допустимо дописывать что угодно и делать как угодно, лишь бы выполнить задачу ...
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.05.2012, 01:43
Ответы с готовыми решениями:

Добавить вывод в файл и чтение из файла объектов класса
Добавить вывод в файл и чтение из файла объектов класса. Работа должна отображаться на мониторе....

Запись и чтение объектов класса в файл С ++
Здравствуйте! Вчера писала сюда по поводу динамического массива, где мне помогли. Сегодня...

Запись в файл и последующее чтение массива типа char
Добрый вечер! Я должен сделать элементарную программу: в текстовом файле изначально лежат...

Добавление вывода в файл и чтения из файла объектов класса
Составить программу на языке С++, с добавлением вывода в файл и чтения из файла объектов...

5
21 / 21 / 7
Регистрация: 06.10.2008
Сообщений: 173
04.05.2012, 09:52 2
почитай об сериализации и xml, очень хороший способ сохранения объектов класса и последующее использование. думаю есть готовые классы в нете для ++.
1
В астрале
Эксперт С++
8048 / 4805 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
04.05.2012, 10:31 3
boost::serialization.
1
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
04.05.2012, 12:16  [ТС] 4
ForEveR, не-не-не. Задача на построение алгоритма вручную, а не на получение результата через реализованую сериализацию бустом или MS в их библиотеках или ещё кем. Приведите пожалуйста "самописный" пример, ато мне вероятно придётся решать такую задачку в очень скором будущем, вот и думаю как правильнее всего это сделать.
0
В астрале
Эксперт С++
8048 / 4805 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
04.05.2012, 12:25 5
Gepar, Не столь просто реализовать грамотную сериализацию.
1
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
05.05.2012, 11:56  [ТС] 6
ForEveR, ну я понял что вот в xml так не напишешь. Ну а вообще как написать вывод в файл чтобы это не получилось быдлокодом. Вот это плохой вариант:

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <list>
using namespace std;
 
class A
{
public:
    A(int _x)
    :x(_x){}
 
    virtual void fun()
    {
        cout<<x<<"\t";
    }
 
    virtual void serialize (ofstream& file)
    {
        file<<x<<' ';
    }
 
private:
    int x;
};
 
class B: public A
{
public:
    B(int _x, int _y)
    :A(_x), y(_y){}
 
    virtual void fun()
    {
        cout<<"B"<<"\t";
        A::fun();
        cout<<y<<endl;
    }
 
    virtual void serialize(ofstream& file)
    {
        A::serialize(file);
        file<<y<<' ';
    }
 
private:
    int y;
};
 
class C: public A
{
public:
    C(int _x, char _c)
    :A(_x), c(_c){}
 
    virtual void fun()
    {
        cout<<"C"<<"\t";
        A::fun();
        cout<<c<<endl;
    }
 
    virtual void serialize(ofstream& file)
    {
        A::serialize(file);
        file<<c<<' ';
    }
 
private:
    char c;
};
 
 
bool writeToFile(list<A*>& x, ofstream& file)
{
    file.clear();
 
    list<A*>::iterator it= x.begin();
    while(it!= x.end() && file.good())
    {
        if(dynamic_cast<C*> (*it))
         file<<"C";
        else if(dynamic_cast<B*> (*it))
         file<<"B";
        else
         file<<"A";
 
        file<<" ";
        (*it++)->serialize(file);
    }
 
    return (file.good() ? true: false);
}
 
 
int main()
{
    A a(1);
    B b(2,2);
    C c(3,'c');
 
    ofstream outFile("file.xml");
 
    list<A*> simpleList;
    list<A*>::iterator it;
    simpleList.push_back(&b);
    simpleList.push_back(&c);
    simpleList.push_back(&a);
 
    writeToFile(simpleList,outFile);
}
?
Скажте если что некрасиво или если вообще идея плохая. Предположительно будет задание написать что-то на наследование и на вывод в файл за часок (на листке), думаю полноценная сериализация как это в MFC или у буста на это время не рассчитывается, рассчитывать будут на что попроще (если вообще такое задание дадут конечно).

Добавлено через 1 минуту
*чтение дописываю просто, спешу показать как я вывожу в файл. Чтение реализовать планирую подобно:
читаю первый символ, switch (символ) case A - читаю как А, case B - читаю как B. Ну вы поняли идею.
Другое дело если скажут " а если у нас тут char* есть поле в классе и мы не знаем его длину и там могут быть переводы строки, а ещё там могут быть скобки (") что тогда, а? Съел, а , съел?"

Добавлено через 17 минут
Дописал чтение из файла, но почему то с тестовыми данными вижу через дебагер что А последнюю (или если последнее что-то другое то это другое) два раза читает, любопытно как это получается оно так...
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <list>
using namespace std;
 
class A
{
public:
    A(int _x)
    :x(_x){}
 
    virtual void fun()
    {
        cout<<x<<"\t";
    }
 
    virtual void serialize (ofstream& file)
    {
        file<<x<<' ';
    }
 
private:
    int x;
};
 
class B: public A
{
public:
    B(int _x, int _y)
    :A(_x), y(_y){}
 
    virtual void fun()
    {
        cout<<"B"<<"\t";
        A::fun();
        cout<<y<<endl;
    }
 
    virtual void serialize(ofstream& file)
    {
        A::serialize(file);
        file<<y<<' ';
    }
 
private:
    int y;
};
 
class C: public A
{
public:
    C(int _x, char _c)
    :A(_x), c(_c){}
 
    virtual void fun()
    {
        cout<<"C"<<"\t";
        A::fun();
        cout<<c<<endl;
    }
 
    virtual void serialize(ofstream& file)
    {
        A::serialize(file);
        file<<c<<' ';
    }
 
private:
    char c;
};
 
 
bool writeToFile(list<A*>& x, ofstream& file)
{
    file.clear();
 
    list<A*>::iterator it= x.begin();
    while(it!= x.end() && file.good())
    {
        if(dynamic_cast<C*> (*it))
         file<<"C";
        else if(dynamic_cast<B*> (*it))
         file<<"B";
        else
         file<<"A";
 
        file<<" ";
        (*it++)->serialize(file);
    }
 
    return (file.good() ? true: false);
}
 
list<A*>* readFromFile(ifstream& file)
{
    file.clear();
    list<A*>* result=new list<A*>;
 
    char ch;
    int x,y;
 
    while(!file.eof() && file.good())
    {
        file>>ch;
        switch(ch)
        {
            case 'A':
            file>>x;
            result->push_back(new A(x));
            break;
 
            case 'B':
            file>>x>>y;
            result->push_back(new B(x,y));
            break;
 
            case 'C':
            file>>x>>ch;
            result->push_back(new C(x,ch));
            break;
 
            default:
            break;
        }
        file.ignore();
    }
    return result;
}
 
 
int main()
{
    A a(1);
    B b(2,2);
    C c(3,'c');
 
    ofstream outFile("file.xml");
 
    list<A*> simpleList;
    list<A*>::iterator it;
    simpleList.push_back(&b);
    simpleList.push_back(&c);
    simpleList.push_back(&a);
 
    writeToFile(simpleList,outFile);
 
    outFile.close();
 
    ifstream inFile("file.xml");
    list<A*>* resultOfReading= readFromFile(inFile);
 
 
    it= resultOfReading->begin();
    while(it!=resultOfReading->end())
    {
        (*it++)->fun();
    }
}
Комментарии не пишу, названия функций говорят сами за себя.

Добавлено через 21 час 29 минут
Ходил вчера на собеседование, задание и правда было такое что нужно написать класс, наследников, а потом вывести в файл и считать из файла. Написал реализацию подобную той что в этой теме, посмотрим что скажут.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.05.2012, 11:56
Помогаю со студенческими работами здесь

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

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

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

Вывод текста из файла в консоль и его последующее редактирование
Задача состоит в следующем: нужно вывести текст из файла расширением, скажем .txt, в консоль, и...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru