Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
0 / 1 / 0
Регистрация: 31.10.2018
Сообщений: 113

Неправильно считываются данные класса из файла

19.05.2019, 17:27. Показов 880. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Я вообще не знаю, что делать, уже столько всего перепробовал!

В общем, у меня есть класс.
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
        class Student
    {
        char * FIO;
        int age;
        int course;
        char gender;
        int perfomance;
    public:
        Student() {};
        Student(const char * FIO_, int age_ = 24, int course_ = 4, char gender_ = 'm', int perfomance_ = 10);
        Student(const Student & st);
        void setSTudent();
        friend void getStudent_from_bin(Student & st);
        friend void setStudent_in_bin(Student & st);
        int getcourse() { return course; } 
        int getage() { return age; }        
        char * getFIO() { return FIO; } 
        int getperfomance() { return perfomance; }
        char getgender() { return gender; } 
        void setcourse(int course_) { course = course_; }
        void setage(int age_) { age = age_; }
        void setFIO(char * FIO_) 
        {
            delete this->FIO;
            this->FIO = new char[sizeof(FIO) / sizeof(char) + 1];
            strncpy_s(this->FIO, sizeof(FIO_) / sizeof(char) + 1, FIO_, sizeof(FIO_) / sizeof(char) + 1); 
        }
        void setperfomance(int perfomance_) { perfomance = perfomance_; }
        void setgender(int gender_) { gender = gender_; }
        void print();
    };
И есть функции записи privat полей класса в бинарник, а также чтения из бинарника.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void getStudent_from_bin(Student & st)
{
    ifstream infile("file.bin", ios::binary);
    infile.read(reinterpret_cast<char*>(st.FIO), strlen(st.FIO) + 1);
    infile.read(reinterpret_cast<char*>(&st.age), sizeof(int));
    infile.read(reinterpret_cast<char*>(&st.course), sizeof(int));//выдает большое значение для course
    infile.read(reinterpret_cast<char*>(&st.gender), sizeof(char));
    infile.read(reinterpret_cast<char*>(&st.perfomance), sizeof(int));
}
void setStudent_in_bin(Student & st)
{
    ofstream infile("file.bin", ios::binary);
    infile.write(reinterpret_cast<char*>(st.FIO), strlen(st.FIO) + 1);
    infile.write(reinterpret_cast<char*>(&st.age), sizeof(int));
    infile.write(reinterpret_cast<char*>(&st.course), sizeof(int));
    infile.write(reinterpret_cast<char*>(&st.gender), sizeof(char));
    infile.write(reinterpret_cast<char*>(&st.perfomance), sizeof(int));
}
Записывает данные функция setStudent_in_bin() вроде нормально, а вот считывает плохо. То имя правильно считает, а потом в поля age и т.д. пишет громадные числа, то имя неправильно читает, и поля опять как хочет заполняет. Делал strlen(st.FIO) и с +1 и без +1, все равно ерунда.
Что я не так делаю?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.05.2019, 17:27
Ответы с готовыми решениями:

Неправильно считываются данные из wav-файла
Всем привет! У меня проблема с получением данных из WAV файла. Почему то функция, которая написана ниже, возвращает размер блока data в 2...

Не считываются данные из файла в объект
Pass_order.h: #pragma once #include&quot;Information_of_Order.h&quot; class Pas_order :public Information_of_Order{ protected: int...

При чтении из файла последние данные считываются дважды !? eof() ?
Есть следующий код: std::ifstream fin(&quot;ParentList&quot;, std::ios::binary); QString str; while(!fin.eof()) { ...

18
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.05.2019, 17:30
Цитата Сообщение от TimaGera31 Посмотреть сообщение
Что я не так делаю?
Ну если не заморачиваться, то определить FIO как char [const_size] или же записывать дополнительное поле, хранящее размер строки
0
0 / 1 / 0
Регистрация: 31.10.2018
Сообщений: 113
19.05.2019, 17:52  [ТС]
Нет, мне это не подходит. Мне нужно много раз создавать имя и я не знаю, какого оно будет размера
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.05.2019, 18:00
Цитата Сообщение от TimaGera31 Посмотреть сообщение
Мне нужно много раз создавать имя и я не знаю, какого оно будет размера
А как вы выделяете память под него если не знаете?
0
0 / 1 / 0
Регистрация: 31.10.2018
Сообщений: 113
19.05.2019, 18:12  [ТС]
Хорошо, если я определю поле char FIO[80], как мне тогда вернуть массив?
0
Модератор
Эксперт С++
 Аватар для zss
13769 / 10962 / 6491
Регистрация: 18.12.2011
Сообщений: 29,237
19.05.2019, 18:14
Вот здесь ошибка:
Цитата Сообщение от TimaGera31 Посмотреть сообщение
C++
1
2
this->FIO = new char[sizeof(FIO) / sizeof(char) + 1]; 
strncpy_s(this->FIO, sizeof(FIO_) / sizeof(char) + 1, FIO_, sizeof(FIO_) / sizeof(char) + 1);
C++
1
2
           this->FIO = new char[ strlen(FIO_)  + 1];
            strcpy_s(this->FIO,  strlen(FIO_)+ 1, FIO_);
Но это Вас не спасет,т.к. при чтении не будете знать, сколько же записано байт.
Рекомендую воспользоваться советом zayats80888 и сделать FIO фиксированного размера.

И, кстати, тогда все данные будут находится в стеке одним куском и их можно прочитать/записать в массив структур так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int getStudent_from_bin(Student* st)
{
    int i=0;
    ifstream infile("file.bin", ios::binary);
    if(infile)
    {
        while( infile.read(reinterpret_cast<char*>(st[i]), sizeof(st)) )
           i++;
        intfile.close();
    }
    return i;//  возвращаем количество прочитанных данных
}
void setStudent_in_bin(Student* st,int n)
{
    ofstream outfile("file.bin", ios::binary);
    if(outfile)
    {
           outfile.write(reinterpret_cast<char*>(st), sizeof(st)*n);
           outfile.close();
    }
}
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.05.2019, 18:16
Цитата Сообщение от TimaGera31 Посмотреть сообщение
как мне тогда вернуть массив?
Всмысле const char* Student::name() const { return FIO; } ?
0
0 / 1 / 0
Регистрация: 31.10.2018
Сообщений: 113
19.05.2019, 18:19  [ТС]
Я нашел способ все заменить, как вы сказали. Это не помогло. Такая же проблема

Добавлено через 2 минуты
Цитата Сообщение от zss Посмотреть сообщение
Вот здесь ошибка:
Сообщение от TimaGera31
C++
1
2
this->FIO = new char[sizeof(FIO) / sizeof(char) + 1];
strncpy_s(this->FIO, sizeof(FIO_) / sizeof(char) + 1, FIO_, sizeof(FIO_) / sizeof(char) + 1);
C++
1
2
* * * * * *this->FIO = new char[ strlen(FIO_) *+ 1];
* * * * * * strcpy_s(this->FIO, *strlen(FIO_)+ 1, FIO_);
Но это Вас не спасет,т.к. при чтении не будете знать, сколько же записано байт.
Рекомендую воспользоваться советом zayats80888 и сделать FIO фиксированного размера.
Я знаю, что тут есть ошибка, но я эту функцию вообще не использую.
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.05.2019, 18:24
TimaGera31, изучай
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
#include <iostream>
#include <fstream>
 
using namespace std;
 
struct Student
{
    char name[20];
    int age;
    //...
};
 
ostream &operator<<(ostream &out, const Student &obj)
{
    return out << obj.name << " " <<
            obj.age << " " << endl;
}
 
int main()
{
    {
        Student arr[]
        {
            {"Ivanov", 1},
            {"Petrov", 2},
            {"Sidorov", 3}
        };
        ofstream out("data.bin", ios::out | ios::trunc | ios::binary);
        out.write((char*)arr, sizeof(arr));
    }
 
    ifstream in("data.bin", ios::in | ios::binary);
    for (Student st; in.read((char*)&st, sizeof(Student)); cout << st);
}
0
0 / 1 / 0
Регистрация: 31.10.2018
Сообщений: 113
19.05.2019, 18:58  [ТС]
Спасибо за пример, я его прочитал, но как мне найти ошибку у меня?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.05.2019, 19:10
Цитата Сообщение от TimaGera31 Посмотреть сообщение
но как мне найти ошибку у меня?
Выкладывай
0
0 / 1 / 0
Регистрация: 31.10.2018
Сообщений: 113
19.05.2019, 19:12  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
Выкладывай
Не понял...
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.05.2019, 19:13
Цитата Сообщение от TimaGera31 Посмотреть сообщение
Не понял...
Где ошибку искать
0
0 / 1 / 0
Регистрация: 31.10.2018
Сообщений: 113
19.05.2019, 19:17  [ТС]
Так я вот и не знаю. Ошибка где-то в записи или чтении файла. Целый день мучаюсь( Я могу весь код скинуть.
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.05.2019, 19:25
Цитата Сообщение от TimaGera31 Посмотреть сообщение
Ошибка где-то в записи или чтении файла.
zss в посте №6 показал как реализовать, там нет ошибки
0
0 / 1 / 0
Регистрация: 31.10.2018
Сообщений: 113
19.05.2019, 20:40  [ТС]
Там совсем все по-другому, мне не нужна новая реализация. Мне нужно узнать, почему не работает то, что я написал
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.05.2019, 21:14
Цитата Сообщение от TimaGera31 Посмотреть сообщение
Мне нужно узнать, почему не работает то, что я написал
Все что вы напишите должно работать? Или как?
Цитата Сообщение от TimaGera31 Посмотреть сообщение
infile.read(reinterpret_cast<char*>(st.F IO), strlen(st.FIO) + 1);
что здесь по вашему происходит?
0
0 / 1 / 0
Регистрация: 31.10.2018
Сообщений: 113
20.05.2019, 02:41  [ТС]
Происходит считывание массива char в переменную st.FIO

Добавлено через 54 секунды
Я не претендую на непогрешимость мысли, я лишь хочу понять свою ошибку
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
20.05.2019, 03:31
Цитата Сообщение от TimaGera31 Посмотреть сообщение
Происходит считывание массива char в переменную st.FIO
FIO это массив char фиксированного размера(если вы исправили), который содержит либо мусор, либо был инициализирован предварительно нуль-терминальной строкой. Поэтому strlen(st.FIO) + 1 возвращает произвольное значение(0, 10, 100500). Вот столько байт вы и считаете из файла. Вам нужно использовать sizeof(FIO) при задании размера считываемого блока, смотрите примеры выше, как читать и писать в бинарном режиме.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.05.2019, 03:31
Помогаю со студенческими работами здесь

Вычислить объем цилиндра. Исходные данные считываются программой из файла. Результат сохранить в файл
Помогите, пожалуйста, с кодом программы на си или си++, заранее большое спасибо! P.S. Нашла только с вводом исходных данных, но...

Неправильно считываются русские символы из консоли
упорно не хочет читать русские символы из консоли :( выводятся нормально, а считывает введенные не правильно ! setlocale(LC_ALL,...

Вычисление интергала, но входные данные сначала считываются из файла, а выходные наоборот в него записываются. Подскажите пожалуйста как это сделать
Заранее спасибо за помощь.) #include&lt;iostream&gt; #include&lt;conio.h&gt; #include &lt;stdio.h&gt; #include &lt;cmath&gt; using namespace std; float...

Неправильно читает данные из файла
Ситуация следующая. Выполняю ввод данных(фамилия и возраст), затем они записываются в структурированный файл(функция newfile). После этого...

Считать данные из файла и записать в вектор (запись происходит неправильно)
есть функция которая читывает с файла и записывает в вектор, но при записывание в в ектор чысла записываються как мусор void...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru