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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.79
moskitos80
61 / 61 / 10
Регистрация: 04.10.2011
Сообщений: 217
Завершенные тесты: 1
#1

Бинарные чтение/запись объектов - C++

13.08.2012, 17:33. Просмотров 1979. Ответов 2
Метки нет (Все метки)

Всем привет. Люди добрые - поможите пожалуйста Написал такой код:
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
#include <iostream>
#include <fstream>
#include <iomanip>
 
using namespace std;
 
/////////////////////////////////////////////////////////////////////////////////
class Person {
    public :
        void setData(void)
        {
            cout << endl << "Enter name . . . "; cin >> this->name;
            cout << endl << "Enter age . . . ";  cin >> this->age;
        }
        void showData(void)
        {
            cout << "Name " << this->name << endl
                 << "Age  " << this->age  << endl;
        }
    protected :
        int age;
        char name[80];
};
/////////////////////////////////////////////////////////////////////////////////
 
int main()
{
    fstream file;
    file.open("PERSON.DAT", ios::in|ios::out|ios::app|ios::binary);
 
    Person pers;
    char choice;
    
    do {
        pers.setData();
        file.write(reinterpret_cast<char*>(&pers), sizeof(pers));
        cout << endl << "Enter more ? (y/n) . . . "; cin >> choice;
    } while (choice != 'n');
 
    file.seekp(ios::beg);
    
    cout << endl << "RESULT: " << endl << endl;
 
    while (!file.eof()) {
        file.read(reinterpret_cast<char*>(&pers), sizeof(pers));
        pers.showData();
        cout << setw(80) << setfill('-') << "" << endl;
    }
 
    return 0;
}
Он просто создаёт файл "PERSON.DAT" в директории, в которой он находится, а потом запрашивает данные у пользователя, и записывает объекты (или наверное правильнее "снимки" объектов) в этот файл. А затем из этого же файла читает данные и выводит в консоль. Беда в том, что последнюю запись он считывает 2 раза!

Никак не пойму в чём дело. Пытался открывать получающийся бинарник - очень похоже, что записи там каждая в одном экземпляре, а последняя почему-то выводится дважды... Подскажите пожалуйста, где я напортачил?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.08.2012, 17:33
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Бинарные чтение/запись объектов (C++):

Бинарные файлы, чтение и запись - C++
Доброго времени суток. Подскажите пожалуйста, как организовать побайтовое чтение и запись данных в бинарный файл. Правильно ли будет...

Бинарные запись и чтение структуры в файл - C++
Записываю структуру в файл.. нужно прочитать.. но он не читает... если delete n; убрать, то &quot;Нарушение прав доступа при записи&quot;. delete n...

fwrite\fread: чтение и запись в бинарные файлы - C++
Добрый день. Пытаюсь разобратся с чтением и записью в бинарные файлы.. в общем обрисую в краце проблему, записываю класс. class tPoint ...

Запись объектов в файл и чтение - C++
#include &lt;fstream.h&gt; #include &lt;iostream.h&gt; #include &lt;conio.h&gt; #include &lt;string.h&gt; class my { int a; float b; char...

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

запись и чтение динамических объектов в файл - C++
Как быть, че делать? Особенно при чтение файла, ведь неизвестно какого он размера. И как бы все это разместить в одной функции, ну например...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Invader_Zim
Twilight Parasite
153 / 149 / 2
Регистрация: 21.07.2011
Сообщений: 907
13.08.2012, 18:18 #2
moskitos80, для проверки сделай записи в файл последовательного доступа.

C++
1
2
3
4
5
    while (!file.eof()) {
        file.read(reinterpret_cast<char*>(&pers), sizeof(pers));
        pers.showData();
        cout << setw(80) << setfill('-') << "" << endl;
    }
попробуй цикл do-while
moskitos80
61 / 61 / 10
Регистрация: 04.10.2011
Сообщений: 217
Завершенные тесты: 1
13.08.2012, 19:12  [ТС] #3
Invader_Zim В файле чётко 3 объекта: файл вЕсит 252 байта. Так что с записью всё ок. Попробовал выводить так Вы посоветовали:
C++
1
2
3
4
5
   do {
        file.read(reinterpret_cast<char*>(&pers), sizeof(pers));
        pers.showData();
        cout << setw(80) << setfill('-') << "" << endl;
    } while (!file.eof());
Увы - не помогло. Эх...

Добавлено через 16 минут
Добавил проверку:
C++
1
2
3
4
5
6
7
8
9
10
11
    do {
        file.read(reinterpret_cast<char*>(&pers), sizeof(pers));
 
        if (!file) {
            cerr << "Error: can`t read from file";
            return 1;
        }
 
        pers.showData();
        cout << setw(80) << setfill('-') << "" << endl;
    } while (file);
Теперь вместо дубля последней записи (в конце) выдаёт ошибку: Error: can`t read from file
Всё-равно непойму что твориться...

Добавлено через 27 минут
Разобрался сам, добавив такую проверку:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    do {
        file.read(reinterpret_cast<char*>(&pers), sizeof(pers));
 
        if (file.eof()) {
            cerr << "End of file ";
            return 1;
        } else if (file.fail()) {
            cerr << "Fail bit ";
            return 1;
        } else if (file.bad()) {
            cerr << "Bad bit ";
            return 1;
        }
 
        pers.showData();
        cout << setw(80) << setfill('-') << "" << endl;
    } while (file);
Понял, что EOF подкрался незаметно а на экран: pers.showData() самый последний раз выводится остаточное значение pers поэтому получается, что последняя запись выводится 2 раза. Проверку на конец файла нужно производить после операции чтения, вот листинг который работает правильно (если кому интересно):

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
#include <iostream>
#include <fstream>
#include <iomanip>
#include "process.h"
using namespace std;
 
/////////////////////////////////////////////////////////////////////////////////
class Person {
    public :
        void setData(void)
        {
            cout << endl << "Enter name . . . "; cin >> this->name;
            cout << endl << "Enter age . . . ";  cin >> this->age;
        }
        void showData(void)
        {
            cout << "Name " << this->name << endl
                 << "Age  " << this->age  << endl;
        }
    protected :
        int age;
        char name[80];
};
/////////////////////////////////////////////////////////////////////////////////
 
const char* FILE_NAME = "C:\\PERSON.DAT";
 
int main()
{
    fstream file;
 
 
    file.open(FILE_NAME, ios::in|ios::out|ios::app|ios::binary);
 
    if (!file) {
        cerr << "Error: can`t open file " << FILE_NAME;
        return 1;
    }
 
    Person pers;
    char choice;
 
    do {
        pers.setData();
        file.write(reinterpret_cast<char*>(&pers), sizeof(pers));
 
        if (!file) {
            cerr << "Error: can`t write in file " << FILE_NAME;
            return 1;
        }
 
        cout << endl << "Enter more ? (y/n) . . . "; cin >> choice;
    } while (choice != 'n');
 
    file.seekp(ios::beg);
    cout << endl << "RESULT: " << endl << endl;
 
    file.read(reinterpret_cast<char*>(&pers), sizeof(pers));
 
    while (!file.eof()) {
        pers.showData();
        cout << setw(80) << setfill('-') << "" << endl;
        file.read(reinterpret_cast<char*>(&pers), sizeof(pers));
    }
 
    return 0;
}
Можно закрыть тему.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.08.2012, 19:12
Привет! Вот еще темы с ответами:

Запись, чтение объектов в файл через указатели. - C++
не могу прочитать объекты из файла. Сломал голову. Все перепробовал. Препод отправил гуглить))). Писать что то вроде пишет? Но что? А...

Запись и чтение объектов разных классов в один файл - C++
Здравствуйте. Изучаю С++ по Лафоре. Дошёл до места, где объясняется, как записывать объекты разных классов в один бинарник. У Лафоре,...

Сериализация объектов с полями std::string + запись/чтение в файл - C++
Здравствуйте! Есть класс: class Guest { private: std::string login;

Бинарные файлы. Чтение - C++
Дан бинарный файл, компонентами которого являются массивы действительных чисел. Вычислить для каждого массива число отрицательных...


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

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

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