Форум программистов, компьютерный форум CyberForum.ru

Написать пару функций для сохранения и восстановления дерева в/из файл (-а) - C++

Восстановить пароль Регистрация
 
roma_m
0 / 0 / 0
Регистрация: 18.02.2014
Сообщений: 36
22.08.2014, 13:14     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #1
Доброго времени суток. Создаю шаблон двоичного дерева на с++. Хочу написать пару функций для сохранения и восстановления дерева в/из файл(-а). Но проблема состоит в том что в качестве данных использую класс с атрибутами:
C++ (Qt)
1
2
3
4
5
6
class Scope
{
private:
    string name;
    int identificalNum;
    float IQ;
А функции выглядят вот так:
C++ (Qt)
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
bool saveTo(const string &fileName)
    {
        FILE *f = fopen(fileName.c_str(), "wb");
        if (f == NULL) return false;
 
        this->saveTree(this->head, f);
 
        fclose(f);
        return true;
    }
 
    void saveTree(TLeaf *&wp, FILE *&f)
    {
        if (wp == NULL)  return;
 
        fwrite((char*)wp->data, 1, sizeof(T), f);
        this->saveTree(wp->left, f);
        this->saveTree(wp->right, f);
    }
 
    bool loadFrom(const string &fileName)
    {
        FILE *f = fopen(fileName.c_str(), "rb");
 
        if ( f == NULL)
            return false;
 
        T *wp = new T();
 
        for(;!feof(f);)
        {
            if(fread((char*)wp, sizeof(T), 1, f))
            {
                this->addLeaf(*wp);
            }
        }
 
        delete wp;
        fclose(f);
        return true;
    }
И вроде как сохранить оно сохранило, а восстановить - проблема. Надеюсь я могу рассчитывать на вашу помощь.
Спасибо
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
-NEURON-
Заблокирован
22.08.2014, 22:13     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #2
Цитата Сообщение от roma_m Посмотреть сообщение
FILE *f = fopen
Прошлый век Используй std::fstream
Цитата Сообщение от roma_m Посмотреть сообщение
this->saveTree(this->head, f);
Для чего тут пишешь this? Обоснуй
Цитата Сообщение от roma_m Посмотреть сообщение
void saveTree(TLeaf *&wp, FILE *&f)
* * {
* * * * if (wp == NULL) *return;
fwrite((char*)wp->data, 1, sizeof(T), f);
* * * * this->saveTree(wp->left, f);
* * * * this->saveTree(wp->right, f);
* * }
что ты этим рекурсивным буллшитом вообще хотел сказать? Сам - то понял?
Цитата Сообщение от roma_m Посмотреть сообщение
class Scope
{
private:
* * string name;
* * int identificalNum;
* * float IQ;
Ты же вроде хотел это сохранять? Ну так сохраняй, сначала длинна строки - потом строка, дальше две POD переменных и по кругу
roma_m
0 / 0 / 0
Регистрация: 18.02.2014
Сообщений: 36
22.08.2014, 23:41  [ТС]     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #3
1. std::fstream тоже не работает так, как я хочу (но могу завтра бросить и с fstream)
2. какой из них: первый или второй
3. предлагай свой вариант обхода двоичного дерева
4. мне нужно сохранить эти 3 поля как 1 кусок памяти (указатель data)

Я пишу (по крайней мере пытаюсь) шаблон для бинарного дерева!!!
-NEURON-
Заблокирован
23.08.2014, 07:04     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #4
Послушай, ты лучше чётко объясни задачу, вот например, у меня все элементы дерева идентичны и мне надо организовать вариацию связанного списка для перехода по ним в такой - то последовательности, а лучше будет, если ты откроешь paint и нарисуешь хоть дрожащей рукой то, что тебе надо
Alex5
881 / 616 / 81
Регистрация: 12.04.2010
Сообщений: 1,552
23.08.2014, 11:13     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #5
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от roma_m Посмотреть сообщение
восстановить - проблема
Пример 1.
C++
1
2
3
4
    string data = "String class /n Strings are objects that represent sequences of characters. /n/n The standard string class provides support for such objects with an interface similar to that of a standard container of bytes, but adding features specifically designed to operate with strings of single-byte characters.";
    int L = data.length(); // примерно 300 байт 
    int n = sizeof(data);  // sizeof(string ) == 24
    fwrite( &data, sizeof(data), 1, f);  // в файл будет записано sizeof(string) == 24 байта
Пример 2.
C++
1
2
3
4
5
6
7
8
9
10
11
12
    struct A
    {
        char* p;
    };
    A a;
    a.p= new char[1000];
    // запишем в  *p  какой-нибудь текст ...
    int n2 = sizeof(A);  // 4 байта
    // ... и попробуем сохранить его в файле 
    fwrite( & a, sizeof(a), 1, f);  
    
    delete[] a.p;
Добавлено через 18 минут

Не по теме:

Цитата Сообщение от -NEURON- Посмотреть сообщение
длина строки
Исправлена опечатка

roma_m
0 / 0 / 0
Регистрация: 18.02.2014
Сообщений: 36
23.08.2014, 22:08  [ТС]     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #6
Это конечно конечно хорошо. Но мне нужно восстановить не сам string, а класс (структуру) с атрибутом(полем) типа string!
У меня получается только выводить только цифровые значения (на char менять не хочу, да и смысл).
Alex5
881 / 616 / 81
Регистрация: 12.04.2010
Сообщений: 1,552
23.08.2014, 22:27     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #7
Цитата Сообщение от roma_m Посмотреть сообщение
Это конечно конечно хорошо
Что хорошо? Вам непонятно, что то, что написано в примерах (сообщение5 ) это очень очень плохо. Поле класса string не содержит, может быть, никакого текста (только указатель). И при записи string в файл, текст в файл не записывается.
Цитата Сообщение от roma_m Посмотреть сообщение
Но мне нужно восстановить ... класс с полем типа string
Наверное, нужно восстановить текст этого string'а? Для этого нужно этот текст записать
roma_m
0 / 0 / 0
Регистрация: 18.02.2014
Сообщений: 36
24.08.2014, 09:11  [ТС]     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #8
Примеры мне понятны.
А восстановить мне нужно вот это:
C++ (Qt)
1
2
3
4
5
6
 class Scope
{
private:
     string name;
     int identificalNum;
     float IQ;
И текст там есть. Но его (текста) восстановление не происходит!

Могу бросить функции вывода на каждого элемента на экран.
Alex5
881 / 616 / 81
Регистрация: 12.04.2010
Сообщений: 1,552
24.08.2014, 12:45     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #9
Цитата Сообщение от roma_m Посмотреть сообщение
И текст там есть.
Где "там"?
Цитата Сообщение от roma_m Посмотреть сообщение
fwrite((char*)wp->data, 1, sizeof(T), f);
Какой тип имеет data?
Цитата Сообщение от roma_m Посмотреть сообщение
восстановить мне нужно вот это:
C++
1
2
3
4
5
6
 class Scope
{
private:
 string name;
 int identificalNum;
 float IQ;
В приведённом (в сообщении 1) коде нигде нет сохранения/восстановления Scope. Как Вы пытаетесь его сохранить?

Об ответах можно только догадываться. Если же data - структура, содержащая string с текстом, то
C++
1
2
/* здесь этот текст в файл записан не будет */
fwrite((char*)wp->data, 1, sizeof(T), f);
roma_m
0 / 0 / 0
Регистрация: 18.02.2014
Сообщений: 36
24.08.2014, 23:21  [ТС]     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #10
Шаблонный класс:

C++ (Qt)
1
2
3
4
5
6
7
template <typename T>
class Tree
{
    typedef struct leaf{
        T *data;
        leaf *right, *left;
    }TLeaf;
Здесь data - это
C++ (Qt)
1
2
3
4
5
6
class Scope
{
private:
    string name;
    int identificalNum;
    float IQ;
И мне нужно из Tree восстановить по одному элементу Scope, который находится в указателе T *data.

Добавлено через 5 минут
Как альтернатива (но к сожалению тоже не работает):

через fstream (ifstream and ofstream)

C++ (Qt)
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
bool save(const string &fname)
    {
        ofstream f;
        f.open(fname.c_str(),ios::out | ios::binary);
 
        if(!f.is_open()) return false;
 
        this->s(this->head, f);
 
        f.close();
        return true;
    }
    void s(TLeaf *&wp, ofstream &f)
    {
        if( wp == NULL) return;
 
        f.write((char*)wp->data, sizeof(T));
        s(wp->left, f);
        s(wp->right, f);
    }
    bool load(const string &fname)
    {
        ifstream file;
        file.open(fname.c_str(),ios::in | ios::binary);
 
        if(!file.is_open()) return false;
 
        T *wp = new T();
 
        for(int var = 0; !file.eof(); ++var)
        {
            cout << var << endl;
            file.read((char*)wp,sizeof(T));
            this->addLeaf(*wp);
            cout << var << endl;
        }
 
        delete wp;
        file.close();
        return true;
    }
Alex5
881 / 616 / 81
Регистрация: 12.04.2010
Сообщений: 1,552
25.08.2014, 17:12     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #11
Цитата Сообщение от roma_m Посмотреть сообщение
нужно восстановить
Чтобы можно было восстановить, нужно записать.
Цитата Сообщение от Alex5 Посмотреть сообщение
C++
1
2
/* здесь текст в файл записан не будет */
fwrite((char*)wp->data, 1, sizeof(T), f);
roma_m
0 / 0 / 0
Регистрация: 18.02.2014
Сообщений: 36
25.08.2014, 22:07  [ТС]     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #12
Хорошо. Ну тогда помогите мне пожалуйста записать.
Alex5
881 / 616 / 81
Регистрация: 12.04.2010
Сообщений: 1,552
26.08.2014, 19:40     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #13
Цитата Сообщение от roma_m Посмотреть сообщение
Хорошо. Ну тогда помогите мне пожалуйста записать.
Можно так, как -NEURON- предложил
Цитата Сообщение от -NEURON- Посмотреть сообщение
class Scope
{
string name;
int identificalNum;
float IQ;
... длина строки, потом строка, дальше две POD переменных и по кругу
roma_m
0 / 0 / 0
Регистрация: 18.02.2014
Сообщений: 36
26.08.2014, 22:42  [ТС]     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #14
Нет, не пойдет.
Мне нужно записать в файл объект класса Scope, а не отдельно по полям класса.
DrOffset
6425 / 3799 / 880
Регистрация: 30.01.2014
Сообщений: 6,592
27.08.2014, 01:00     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #15
Цитата Сообщение от roma_m Посмотреть сообщение
Нет, не пойдет.
Мне нужно записать в файл объект класса Scope, а не отдельно по полям класса.
Ты, в этом случае, не сможешь это сделать. std::string использует динамическую память и она не сохранится в файл при простом побайтовом копировании объекта в файл. Плюс к этому, так сохранять "можно" только объекты POD типов, они не имеют нетривиальных конструкторов и не содержат полей с такими конструкторами (также не содержат виртуальных функций, нетривиальных деструкторов, и т.д.). Если объект имеет нетривиальный конструктор, то он должен быть сконструирован с помощью него, другие варианты ведут к UB. И еще плюс к этому, даже если тип - POD, то при таком сохранении всегда нужно помнить про выравнивание.

Прочитай про сериализацию и зачем она нужна. Это в целом решает твою проблему. И объясни хотя бы себе, чем принципиально должна отличаться запись объекта целиком, как ты хочешь, от записи его полей последовательно?
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6167 / 2896 / 282
Регистрация: 04.12.2011
Сообщений: 7,698
Записей в блоге: 3
27.08.2014, 01:43     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #16
Цитата Сообщение от roma_m Посмотреть сообщение
Мне нужно записать в файл объект класса Scope, а не отдельно по полям класса.
roma_m, в файлпоток пишется последовательность байтов. Более того, в памяти объекты тоже цепочки байтов, которые рассматриваются как объекты. Самый простой путь, это заселить память используя конструктор или конструирующий метод . Это значит, что можно например, имея дерево получить исходное сырьё которым питается конструктор которым оно было построено. Тогда оператор << будет содержать код извлекающий это сырьё из дерева, а оператор >> создаст из него объект корня и заселит всё дерево. Например в общем случае, если речь бы шла о дереве разбора выражения, то сохранялось бы выражение, а потом из него восстанавливалось дерево. Надёжность состоит в том, что сначала прочитается то, что нужно, а потом уже будет построен весь объект. Хотя, наверное есть ещё много вариантов. Если уж так важно, чтобы дерево сохранялось именно в том состоянии как в момент сохранения, придётся сочинять формат, который это учитывает. Мне самому интересно, есть ли стандартные подходы для этого случая.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.08.2014, 02:08     Написать пару функций для сохранения и восстановления дерева в/из файл (-а)
Еще ссылки по теме:

Написать программу для создания триарного дерева. C++
Написать кольцевой список с возможностями добавления, удаления и поиска элементов, и сохранения в файл. C++
Написать перегруженные шаблоны функций для уравнений C++

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

Или воспользуйтесь поиском по форуму:
Alex5
881 / 616 / 81
Регистрация: 12.04.2010
Сообщений: 1,552
27.08.2014, 02:08     Написать пару функций для сохранения и восстановления дерева в/из файл (-а) #17
Цитата Сообщение от roma_m Посмотреть сообщение
Но его (текста) восстановление не происходит!
Цитата Сообщение от roma_m Посмотреть сообщение
Мне нужно записать в файл объект класса Scope, а не отдельно по полям класса.
roma_m, что же Вам нужно? Нужно или нет сохранять текст? Объект класса Scope не содержит текста.
Yandex
Объявления
27.08.2014, 02:08     Написать пару функций для сохранения и восстановления дерева в/из файл (-а)
Ответ Создать тему
Опции темы

Текущее время: 23:26. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru