Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
Symblight
8 / 4 / 2
Регистрация: 24.04.2015
Сообщений: 97
Завершенные тесты: 1
1

Как сделать сохранение/загрузку данных из бинарного файла через классы?

26.04.2017, 12:56. Просмотров 838. Ответов 16
Метки нет (Все метки)

Есть класс Students.
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
class Students{
public:
 
    void save();
    void load();
 
    ~Students();
 
    //Конструктор класса Students
    Students(string firstname, string lastname);
 
    //Установка имени
    void set_firstname(string);
    //Получение имени
    string get_firstname();
 
    //Установка фамилии
    void set_lastname(string);
    //Получение фамилии
    string get_lastname();
 
private:
    //Имя
    string firstname;
    //Фамилия
    string lastname;
};
C++
1
2
3
4
5
6
Сам конструктор: <code lang="cpp">
Students::Students(string firstname, string lastname)
{
    Students::set_firstname(firstname);
    Students::set_lastname(lastname);
}
С сохранением вроде разобрался:
C++
1
2
3
4
5
6
7
8
9
10
11
12
void Students::save() {
    ofstream fout("Students.dat", ios::binary | ios::out);
    
    string firstname = Students::get_firstname();
    string lastname = Students::get_lastname();
 
    fout.write((char*)&lastname, sizeof(firstname));
    fout.write((char*)&lastname, sizeof(lastname));
 
    fout << std::endl;
    fout.close();
}
Но с загрузкой возникли проблемы. Сама форма обращается к Main.cpp, логика в этом файле Там я обращаюсь уже к Students.h.
Задача стоит такая: Нужно загрузить список студентов (из бинарного файла) Изменить любого студента и сохранить его в тот же файл. Как я понял нужно загружать в файл массив Students, далее после редактирования какого либо элемента массива - возвращать новый массив и записывать в файл.
Сам вопрос заключается в том, как это сделать через классы, конструкторы и декструктор? Как грамотно это реализовать?
Описание конструкторов и функции класса находятся в файле Students.cpp. Логика программы в Main.cpp
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.04.2017, 12:56
Ответы с готовыми решениями:

Помогите сделать сохранение и загрузку данных
народ есть вот такая программа: #include &lt;conio.h&gt; #include &lt;iostream.h&gt;...

Как записывать и считывать не POD типы данных из бинарного файла?
Есть класса в котором часть полей не базовых динамических типов например vector...

пытаюсь сделать реализацию через считывание из файла кол-ва чисел, i,но незнаю как сделать реализацию из файла в массив и сортировки.
В файле input.txt находится неизвестное количество вещественных чисел в...

Нужно создать базу данных (создать пустой бинарный файл). Через поток. Поток бинарного файла описать в виде локальной переменной внутри функции.
Совсем не понял эту тему. Нужно создать базу данных (создать пустой бинарный...

Чтение данных из бинарного файла
читаю по while (!stream.eof()), проблема в том что в конце в условие лишний раз...

16
Dani
1393 / 637 / 134
Регистрация: 11.08.2011
Сообщений: 2,299
Записей в блоге: 2
Завершенные тесты: 1
26.04.2017, 13:02 2
Цитата Сообщение от Symblight Посмотреть сообщение
C++
1
2
fout.write((char*)&lastname, sizeof(firstname));
fout.write((char*)&lastname, sizeof(lastname));
1) В первой строке должно быть sizeof(lastname)
2) В файл запишутся данные объекта string, а саму строку он хранит в каком-то массиве по указателю (массив выделяется динамически, т.е. объект хранит только указатель на этот массив). Поэтому в файл запишется не массив, а только указатель на него, который будет не валидным, если память, выделенную под массив освободят. Поэтому вместо lastname пиши lastname.c_str() и не sizeof, а lastname.length().
0
Symblight
8 / 4 / 2
Регистрация: 24.04.2015
Сообщений: 97
Завершенные тесты: 1
26.04.2017, 13:24  [ТС] 3
Это я учел. А как написать функцию которая будет загружать массив в файл и выгружать через этот класс? И где описывать функцию, в классе или делать отдельно?

Добавлено через 14 минут
DaniОшибка &: недопустимая операция с выражением привязанной функции-члена. Если добавить .c_str
0
nd2
2835 / 2403 / 1057
Регистрация: 29.01.2016
Сообщений: 8,046
26.04.2017, 13:32 4
Цитата Сообщение от Symblight Посмотреть сообщение
Это я учел.
А учёл, что строки имеют разную длину? Поэтому, вот этого недостаточно:
Цитата Сообщение от Dani Посмотреть сообщение
вместо lastname пиши lastname.c_str() и не sizeof, а lastname.length().
Как потом читать их будешь?
0
Dani
1393 / 637 / 134
Регистрация: 11.08.2011
Сообщений: 2,299
Записей в блоге: 2
Завершенные тесты: 1
26.04.2017, 13:50 5
Цитата Сообщение от Symblight Посмотреть сообщение
&: недопустимая операция с выражением привязанной функции-члена.
Там & не нужен, т.к. c_str() уже возвращает указатель.
Цитата Сообщение от nd2 Посмотреть сообщение
Как потом читать их будешь?
Я в общем обрисовал, что надо сделать. Например, можно lastname.length() + 1 и выводим еще '\0'. Теперь можем разбить строки (где кончается одна и начинается следующая). Или можно вывести еще длину в начале. Но и так и так lastname.c_str() и lastname.length()
0
Max Dark
шКодер самоучка
1968 / 1745 / 860
Регистрация: 09.10.2013
Сообщений: 3,854
Записей в блоге: 6
Завершенные тесты: 2
26.04.2017, 13:52 6
как то так
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
class Students {
public:
    // ....
    static std::ofstream& write(std::ofstream &fout, const Students& st);
    static std::ifstream& read(std::ifstream &fin, Students& st);
    // ....
};
 
std::ofstream& write_string(std::ofstream &fout, const std::string& str)
{
    std::string::size_type size = str.size();
    fout.write(reinterpret_cast<const char*>(&size), sizeof(size));
    fout.write(str.c_str(), size);
    return fout;
}
 
std::ifstream& read_string(std::ifstream &fin, std::string& str)
{
    std::string::size_type size = 0;
    if(fin.read(reinterpret_cast<char*>(&size), sizeof(size)))
    {
        char* tmp = new char[size];
        if (fin.read(tmp, size))
        {
            str = std::string(tmp, tmp + size);
        }
        delete [] tmp;
    }
    
    return fin;
}
 
 
std::ofstream& Students::write(std::ofstream &fout, const Students& st)
{
    write_string(fout, st.firstname);
    write_string(fout, st.lastname);
    return fout;
}
 
std::ifstream& Students::read(std::ifstream &fin, Students& st)
{
    std::string firstname, lastname;
    if(read_string(fin, firstname) &&  read_string(fin, lastname))
    {
        st = Students(firstname, lastname);
    }
    return fin;
}
0
nd2
2835 / 2403 / 1057
Регистрация: 29.01.2016
Сообщений: 8,046
26.04.2017, 14:12 7
Цитата Сообщение от Dani Посмотреть сообщение
Я в общем обрисовал
Я это и уточнил для ТС.
0
Symblight
8 / 4 / 2
Регистрация: 24.04.2015
Сообщений: 97
Завершенные тесты: 1
26.04.2017, 14:45  [ТС] 8
Max Dark, А есть пример какой нибудь? Просто я хочу выводит в программу список студентов, добавить или изменить и все это с применением Классов, конструкторов и т.д. Я не могу понять в том, что вы показали.
0
Max Dark
шКодер самоучка
1968 / 1745 / 860
Регистрация: 09.10.2013
Сообщений: 3,854
Записей в блоге: 6
Завершенные тесты: 2
26.04.2017, 14:57 9
Symblight, что именно непонятно?
0
Symblight
8 / 4 / 2
Регистрация: 24.04.2015
Сообщений: 97
Завершенные тесты: 1
26.04.2017, 15:18  [ТС] 10
Max Dark, std::ofstream& write_string std::ifstream& read_string это в классе описывается?
0
Max Dark
шКодер самоучка
1968 / 1745 / 860
Регистрация: 09.10.2013
Сообщений: 3,854
Записей в блоге: 6
Завершенные тесты: 2
26.04.2017, 15:27 11
Цитата Сообщение от Symblight Посмотреть сообщение
это в классе описывается?
нет.
write_string вспомогательная функция для записи строк в двоичный файл
read_string вспомогательная функция для чтения строк из двоичного файла.
Они не относятся к какому либо классу и могут использоваться отдельно.
0
Symblight
8 / 4 / 2
Регистрация: 24.04.2015
Сообщений: 97
Завершенные тесты: 1
26.04.2017, 16:22  [ТС] 12
Max Dark, А можно как то так сделать?
C++
1
2
3
Students**store = new Students*[x];
for(int m=0;m<x;m++)
    store[m] = new Students(stuff);
0
Max Dark
шКодер самоучка
1968 / 1745 / 860
Регистрация: 09.10.2013
Сообщений: 3,854
Записей в блоге: 6
Завершенные тесты: 2
26.04.2017, 16:29 13
Symblight, можно.
0
Symblight
8 / 4 / 2
Регистрация: 24.04.2015
Сообщений: 97
Завершенные тесты: 1
26.04.2017, 16:30  [ТС] 14
Max Dark, Только как в таком случае записывать. store[m]->save()? Мне кажется это плохо скажется для оптимизации.
0
Max Dark
шКодер самоучка
1968 / 1745 / 860
Регистрация: 09.10.2013
Сообщений: 3,854
Записей в блоге: 6
Завершенные тесты: 2
26.04.2017, 16:40 15
Лучший ответ Сообщение было отмечено Symblight как решение

Решение

Цитата Сообщение от Symblight Посмотреть сообщение
Только как в таком случае записывать.
C++
1
2
3
4
5
std::ofstream fout("Students.dat", ios::binary | ios::out);
for(int m=0;m<x;++m) {
    Students::write(fout, *store[m]);
}
fout.close();
1
Symblight
8 / 4 / 2
Регистрация: 24.04.2015
Сообщений: 97
Завершенные тесты: 1
27.04.2017, 09:55  [ТС] 16
Max Dark, конструктор write считывает с аргумента st firstname и lastname. А как помещать эти аргументы в массив перед тем как обращаться к write?
0
Max Dark
шКодер самоучка
1968 / 1745 / 860
Регистрация: 09.10.2013
Сообщений: 3,854
Записей в блоге: 6
Завершенные тесты: 2
27.04.2017, 10:56 17
Цитата Сообщение от Symblight Посмотреть сообщение
конструктор write
Students::write не является конструктором(как и Students::read) - это просто функции.
Цитата Сообщение от Symblight Посмотреть сообщение
А как помещать эти аргументы в массив перед тем как обращаться к write?
С обычными массивами(int*, double* и т.д.) дело имели? Ну вот тут то же самое.
0
27.04.2017, 10:56
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.04.2017, 10:56

Считывание данных из бинарного файла
Доброго времени суток. Моя проблема уже была озвучена в теме. Вот листинг...

Чтение данных из бинарного файла
программа должна считывать данные из бинарного файла, записывать их в...

Вывод на экран данных их бинарного файла
Привет, народ. Выручайте пожалуйста. Никак не могу сообразить, как вывести на...


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

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

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