Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 19.11.2018
Сообщений: 14
1

Запись и чтение вектора структур в бинарный файл(2)

26.11.2018, 13:57. Показов 1543. Ответов 5
Метки нет (Все метки)

Есть заполненный вектор структур. Структура вида:
C++
1
2
3
4
5
struct struc {
    string a;
    int x;
    map<int, int>m;
};
Написал две функции для записи и чтения, в функции передаю сам вектор и путь к файлу:
void fout(vector<struc>&arr, string path)
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
{
    ofstream fl(path, ios::binary);
 
    size_t sz = arr.size();
    fl.write(reinterpret_cast<char*>(&sz), sizeof(size_t));
 
    for (auto &elem: arr)
    {
        size_t area_size = elem.a.size();
        fl.write(reinterpret_cast<char*>(&area_size), sizeof(size_t));
        fl.write(elem.a.data(), area_size);
 
        fl.write(reinterpret_cast<char*>(&elem.x), sizeof(int));
 
        size_t map_size = elem.m.size();
        fl.write(reinterpret_cast<char*>(&map_size), sizeof(size_t));
        for (auto &i : elem.m)
        {
            int a = i.first;
            int b = i.second;
            fl.write(reinterpret_cast<char*>(&a), sizeof(int));
            fl.write(reinterpret_cast<char*>(&b), sizeof(int));
        }
    }
    fl.close();
}
 
void fin(vector<struc>&arr, string path)
{
    ifstream fl1(path, ios::binary);
 
    size_t sz;
    fl1.read(reinterpret_cast<char*>(&sz), sizeof(size_t));
    arr.resize(sz);
 
    struc s;
    vector<char> aa;
 
    for (size_t i = 0; i < sz; ++i)
    {
        size_t area_size;
        fl1.read(reinterpret_cast<char*>(&area_size), sizeof(size_t));
        aa.resize(area_size + 1);
        fl1.read(aa.data(), area_size);
        aa[area_size] = '\0';
        s.a = aa.data();
 
        fl1.read(reinterpret_cast<char*>(&s.x), sizeof(int));
 
        size_t map_size;
        fl1.read(reinterpret_cast<char*>(&map_size), sizeof(size_t));
        for (size_t j = 0; j < map_size; ++j)
        {
            int a, b;
            fl1.read(reinterpret_cast<char*>(&a), sizeof(int));
            fl1.read(reinterpret_cast<char*>(&b), sizeof(int));
            s.m[a] = b;
        }
 
        arr[i] = s;
    }
 
    fl1.close();
}
Все хорошо, но обнаружил проблему, что на выводе получаем вот это:
Название района:q
Количество школ в районе:1
Школа №1 - Количество медалистов: 2

Название района:w
Количество школ в районе:1
Школа №1 - Количество медалистов: 2
Школа №2 - Количество медалистов: 3

Название района:e
Количество школ в районе:1
Школа №1 - Количество медалистов: 2
Школа №2 - Количество медалистов: 3
Школа №3 - Количество медалистов: 4

То есть, при заполнении в каждом районе вводил по одной школе, но как можно заметить школы из предыдущих районов почему-то копируются в следующие. Заполнение структуры до записи в файл работает корректно, проверял. Дело точно в этих двух функциях, но что именно так и не могу найти.

на всякий случай функции заполнения и печати тоже оставлю:
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
vector<struc> zapolnenie(vector<struc>&arr, int areas) {
    int n = 0, a = 0, b = 0;
    string s;
    for (int i = 0; i < areas; i++) {
        cout << "\nНазвание района:" << endl;
        cin >> s;
        cout << "\nКоличество школ в районе:" << endl;
        cin >> n;
        arr[i].a = s;
        arr[i].x = n;
        for (int j = 0; j < n; j++) {
            cout << "Номер школы:" << endl;
            cin >> a;
            cout << "Количество медалистов в школе:" << endl;
            cin >> b;
            arr[i].m.insert(pair<int, int>(a, b));
        }
    }
    return arr;
}
 
void print(vector<struc>&arr) {
    for (auto i : arr) {
        cout << "\nНазвание района:" << i.a << "\nКоличество школ в районе:" << i.x << endl;
        for (auto el : i.m) {
            cout << "Школа №" << el.first << " - Количество медалистов: " << el.second << endl;
        }
    }
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.11.2018, 13:57
Ответы с готовыми решениями:

Запись и чтение вектора структур в бинарный файл
Есть заполненный вектор структур. Структура вида: struct struc { string a; int x; map&lt;int,...

Запись/чтение массива структур в бинарный файл
#include &lt;iostream&gt; #include &lt;fstream&gt; using namespace std; struct test { int x; ...

Запись в бинарный файл и чтение из него массива структур
Здравствуйте, появилась проблема записью структуры в бинарный файл и чтение из него этой же...

Запись в бинарный файл и чтение из него массива структур
Ребята, выручайте. Огромная проблема с записью и с чтением структуры из бинарного файла. Помогите...

5
259 / 109 / 53
Регистрация: 22.01.2017
Сообщений: 435
26.11.2018, 15:10 2
Kot_Fed0t, с заполнением непонятно. Сразу может заполняться несколько районов? И зачем передавать ссылку на arr и возвращать ее?
ИМХО, так логичнее:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struc zapolnenie() {
    int n = 0, a = 0, b = 0;
    string s;
    struc el;
    cout << "\nНазвание района:" << endl;
    cin >> s;
    cout << "\nКоличество школ в районе:" << endl;
    cin >> n;
    el.a = s;
    el.x = n;
    for (int j = 0; j < n; j++) {
        cout << "Номер школы:" << endl;
        cin >> a;
        cout << "Количество медалистов в школе:" << endl;
        cin >> b;
        el.m.insert(pair<int, int>(a, b));
    }
 
    return el;
}
 
// Вызов
arr.push_back(zapolnenie());
0
0 / 0 / 0
Регистрация: 19.11.2018
Сообщений: 14
26.11.2018, 15:18  [ТС] 3
Цитата Сообщение от n1b1ru Посмотреть сообщение
Kot_Fed0t, с заполнением непонятно. Сразу может заполняться несколько районов? И зачем передавать ссылку на arr и возвращать ее?
ИМХО, так логичнее:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struc zapolnenie() {
    int n = 0, a = 0, b = 0;
    string s;
    struc el;
    cout << "\nНазвание района:" << endl;
    cin >> s;
    cout << "\nКоличество школ в районе:" << endl;
    cin >> n;
    el.a = s;
    el.x = n;
    for (int j = 0; j < n; j++) {
        cout << "Номер школы:" << endl;
        cin >> a;
        cout << "Количество медалистов в школе:" << endl;
        cin >> b;
        el.m.insert(pair<int, int>(a, b));
    }
 
    return el;
}
 
// Вызов
arr.push_back(zapolnenie());
да в том то и дело, что нужно заполнить несколько районов с некоторым количеством школ в нем.
0
259 / 109 / 53
Регистрация: 22.01.2017
Сообщений: 435
26.11.2018, 15:29 4
Kot_Fed0t, если функция вызывается несколько раз arr будет перезаписываться.
Как вызывается функция с выводом из поста №1?
0
0 / 0 / 0
Регистрация: 19.11.2018
Сообщений: 14
26.11.2018, 17:12  [ТС] 5
Цитата Сообщение от n1b1ru Посмотреть сообщение
Kot_Fed0t, если функция вызывается несколько раз arr будет перезаписываться.
Как вызывается функция с выводом из поста №1?
вот так примерно:
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
#include "pch.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
 
using namespace std;
 
struct struc {
    string a;
    int x;
    map<int, int>m;
};
 
 
vector<struc> zapolnenie(vector<struc>&arr, int areas) {
    int n = 0, a = 0, b = 0;
    string s;
    for (int i = 0; i < areas; i++) {
        cout << "\nНазвание района:" << endl;
        cin >> s;
        cout << "\nКоличество школ в районе:" << endl;
        cin >> n;
        arr[i].a = s;
        arr[i].x = n;
        for (int j = 0; j < n; j++) {
            cout << "Номер школы:" << endl;
            cin >> a;
            cout << "Количество медалистов в школе:" << endl;
            cin >> b;
            arr[i].m.insert(pair<int, int>(a, b));
        }
    }
    return arr;
}
 
void fout(vector<struc>&arr, string path)
{
    int a, b;
    ofstream fl(path, ios::binary);
 
    size_t sz = arr.size();
    fl.write(reinterpret_cast<char*>(&sz), sizeof(size_t));
 
    for (auto &elem : arr)
    {
        size_t area_size = elem.a.size();
        fl.write(reinterpret_cast<char*>(&area_size), sizeof(size_t));
        fl.write(elem.a.data(), area_size);
 
        fl.write(reinterpret_cast<char*>(&elem.x), sizeof(int));
 
        size_t map_size = elem.m.size();
        fl.write(reinterpret_cast<char*>(&map_size), sizeof(size_t));
        for (auto &i : elem.m)
        {
            a = i.first;
            b = i.second;
            fl.write(reinterpret_cast<char*>(&a), sizeof(int));
            fl.write(reinterpret_cast<char*>(&b), sizeof(int));
        }
    }
    fl.close();
}
 
void fin(vector<struc>&arr, string path)
{
    int a, b;
    ifstream fl1(path, ios::binary);
 
    size_t sz;
    fl1.read(reinterpret_cast<char*>(&sz), sizeof(size_t));
    arr.resize(sz);
 
    struc s;//структура для записи в вектор arr
    vector<char> aa;
 
    for (size_t i = 0; i < sz; i++)
    {
        size_t area_size;
        fl1.read(reinterpret_cast<char*>(&area_size), sizeof(size_t));
        aa.resize(area_size + 1);
        fl1.read(aa.data(), area_size);
        aa[area_size] = '\0';
        s.a = aa.data();
 
        fl1.read(reinterpret_cast<char*>(&s.x), sizeof(int));
 
        size_t map_size;
        fl1.read(reinterpret_cast<char*>(&map_size), sizeof(size_t));
        for (size_t j = 0; j < map_size; j++)
        {
            fl1.read(reinterpret_cast<char*>(&a), sizeof(int));
            fl1.read(reinterpret_cast<char*>(&b), sizeof(int));
            s.m[a] = b;
        }
        arr[i] = s;
    }
 
    fl1.close();
}
 
void print(vector<struc>&arr) {
    for (auto i : arr) {
        cout << "\nНазвание района:" << i.a << "\nКоличество школ в районе:" << i.x << endl;
        for (auto el : i.m) {
            cout << "Школа №" << el.first << " - Количество медалистов: " << el.second << endl;
        }
    }
}
 
 
 
int main()
{
    setlocale(LC_ALL, "Russian");
    int areas = 0, n = 0, j = 0, a = 0, b = 0, med = 0, k = 0;
    string path = "text.txt";
    string path2 = "text2.txt";
    string s;
    cout << "Введите количество районов:" << endl;
    cin >> areas;
    vector<struc>arr(areas);
    vector<struc>arr2;
    vector<struc>arr3(areas);
    vector<struc>arr4(areas);
    
 
    // создание и заполнение файла
    arr = zapolnenie(arr, areas);//заполнили вектор структур
 
    fout(arr, path);//записали в файл
 
    ///вывод содержимого 1 файла
    fin(arr2, path);//записали из файла в вектор
 
    print(arr2);//распечатали
}
0
259 / 109 / 53
Регистрация: 22.01.2017
Сообщений: 435
26.11.2018, 20:51 6
Лучший ответ Сообщение было отмечено Kot_Fed0t как решение

Решение

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
void fin(vector<struc>&arr, string path)
{
    ifstream fl1(path, ios::binary);
 
    size_t sz;
    fl1.read(reinterpret_cast<char*>(&sz), sizeof(size_t));
 
    int a, b;
    vector<char> aa;
    size_t area_size;
 
    for (size_t i = 0; i < sz; i++)
    {
        fl1.read(reinterpret_cast<char*>(&area_size), sizeof(size_t));
        aa.resize(area_size + 1);
        fl1.read(aa.data(), area_size);
        aa[area_size] = '\0';
 
        struc s; // Структура в цикле
        s.a = aa.data();
 
        fl1.read(reinterpret_cast<char*>(&s.x), sizeof(int));
 
        size_t map_size;
        fl1.read(reinterpret_cast<char*>(&map_size), sizeof(size_t));
        for (size_t j = 0; j < map_size; j++)
        {
            fl1.read(reinterpret_cast<char*>(&a), sizeof(int));
            fl1.read(reinterpret_cast<char*>(&b), sizeof(int));
            s.m.insert(pair<int, int>(a, b)); // Заменил
        }
        arr.push_back(s); // Заменил
    }
 
    fl1.close();
}
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.11.2018, 20:51

Запись вектора uin8_t в бинарный файл и обратное чтение из файла
Здравствуйте. Есть std::vector&lt;uint8_t&gt;. Нужно записать все элементы в бинарный файл, а затем...

Считывание и запись структур в бинарный файл
Здравствуйте, я делаю автоподгрузку и авто сохранение некоторой структуры в бинарный файл. И где-то...

Запись массива структур в бинарный файл
Есть структура Owner: struct Owner{ char name; unsigned int purse; short catb; ...

Запись массива структур в бинарный файл
Одно из полей структуры типа String, нужно записать массив структур в бинарный файл: struct...


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

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

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