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

Управление двоичными файлами с записями фиксированной длины.Разбиаение записи на команды

19.10.2022, 23:28. Показов 2147. Ответов 23

Студворк — интернет-сервис помощи студентам
Имеется задача. Честно говоря, не знаю как подступиться ни с точки зрения кода ни алгоритмически. Очень плохо даётся всё связанное с двоичными файлами, да и в принципе по работе с файлами (Крайне буду благодарен литературе по работе с файлами и не только на с++)

Нужно программу управления двоичными файлами с записями фиксированной длины

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

Сама задача: Книга: ISBN – двенадцатизначное число, автор, название, год издания.

Требования к подготовке и выполнению задания
1) Разработать структуру записи двоичного файла согласно варианту задания.
2) Подготовить тестовые данные в текстовом файле с кодировкой ASCII, в соответствии со структурой записи варианта.
3) При открытии файла выполнить контроль его существования и открытия.

Примечание. Реализация операций по чтению данных из файла будет проще, если значение для каждого поля записи размещать на отдельной строке текстового редактора.
Имя файла вводит пользователь.
При открытии файла обеспечить контроль существования и открытия файла.
При применении механизма прямого доступа к записи файла выполнить контроль присутствия записи с заданным номером в файле.

Проблема в том, что неясно как вообще алгоритмически это сделать. Вроде как тут нужно двойное хэширование, но тогда вопрос встает в реализации. Прошу совета в алгоритме или коде или любая другая инфа по данной теме. Кто чем может
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.10.2022, 23:28
Ответы с готовыми решениями:

Создать текстовый файл с записями фиксированной длины.
Создать текстовый файл с записями фиксированной длины. Файл содержит информацию о стоимости 10 наименований товаров в различных...

Работа с двоичными файлами: слова заданной длины
Работа с двоичными файлами: Создать файл, состоящий из слов. Вывести на экран все слова, длина которых равна заданному числу.

Строку произвольной длины разрезать на несколько строк фиксированной длины
Есть строка большой длины (до 2000 символов) - последние символы в строке ~^, нужно разделить эту строку на несколько строк не более 200...

23
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
20.10.2022, 03:13
Лучший ответ Сообщение было отмечено daniil_novel как решение

Решение

Студворк — интернет-сервис помощи студентам
Цитата Сообщение от daniil_novel Посмотреть сообщение
Да вроде бы надо через потоки, но пока с реализацией туго
Простенький пример, с ручным созданием файла, прикрепил.
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
#include <iostream>
#include <fstream>
struct Book{
   char isbn[14];
   char author[32];
   char name[32];
   uint16_t year;
};
// выровненная на тестируемой платформе структура размером (80байт) кратная 8
// нужно в коде при компиляции это проверять, например
static_assert((sizeof(Book)==80));
int main()
{
    std::fstream f("bd.bin", std::ios::in | std::ios::out | std::ios::binary | std::ios::ate); // открыли с установкой позиции на конец файла
    if (f.is_open()){
        std::size_t size = f.tellg();
        std::cout << "filesize : " << size << std::endl;        
        Book b;
        f.seekg(sizeof(Book)*(2-1)); // переместились ко второй записи
        f.read((char*)&b, sizeof(Book));
        std::cout << b.isbn << ' ' << b.year;
    }
    std::cin.get();
}
Вложения
Тип файла: rar BookBD.rar (15.7 Кб, 2 просмотров)
1
1 / 1 / 0
Регистрация: 19.03.2022
Сообщений: 99
20.10.2022, 04:19  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
daniil_novel, это особенности реализации.
Вот, кстати, что по итогу вышло спустя половину бессоной ночи. Надеюсь на критику. Сейчас работает без ошибок вроде как

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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
 
using namespace std;
 
struct Book {
    char Isbn[13];
    char Author[33];
    char Name[33];
    uint16_t  Year;
};
 
using namespace std;
 
int CreateBoolTxt(string nametf, string namebf) {
    ifstream itf(nametf);
    if(itf)
    {
        fstream obf(namebf, ios::out | ios::binary);
        Book Bk;
        while(!itf.eof())
        {
            itf >> Bk.Isbn;
            itf >> Bk.Author;
            itf.get();
            itf.getline(Bk.Name, 33, '\n');
            itf >> Bk.Name;
            obf.write((char*)&Bk, sizeof(Book));
        }
        itf.close();
        obf.close();
        return 0;
    }
    return 1;
}
 
int PoiskISBNInBinFile(string namebf, char isbn)
{
    ifstream bf;
    bf.open(namebf, ios::binary);
    Book Bk;
    int numRecord = 0;
    bf.read((char*)&Bk, sizeof(Book));
    while(!bf.eof())
    {
        if(*Bk.Isbn == isbn)
        {
            bf.close();
            return numRecord;
        }
        numRecord++;
        bf.read((char*)&Bk, sizeof(Book));
    }
    bf.close();
    return -1;
}
 
int PoiskAuthorInBinFile(string namebf, char author)
{
    ifstream bf;
    bf.open(namebf, ios::binary);
    Book Bk;
    int numRecord = 0;
    bf.read((char*)&Bk, sizeof(Book));
    while(!bf.eof())
    {
        if(*Bk.Author == author)
        {
            bf.close();
            return numRecord;
        }
        numRecord++;
        bf.read((char*)&Bk, sizeof(Book));
    }
    bf.close();
    return -1;
}
 
void NewFileBin(string namebf, char isbn, string namenewbf)
{
    ifstream bf;
    bf.open(namebf, ios::binary);
    Book Bk;
    fstream obf(namenewbf, ios::out | ios::binary);
    bf.read((char*)&Bk, sizeof(Book));
    while(!bf.eof())
    {
        if(*Bk.Isbn == isbn)
        {
            obf.write((char*)&Bk, sizeof(Book));
        }
        bf.read((char*)&Bk, sizeof(Book));
    }
    bf.close();
    obf.close();
}
 
void DeleteBin(string namebf, unsigned int n)
{
    ifstream bf;
    bf.open(namebf, ios::binary);
    Book r;
    vector <Book> a;
    bf.read((char*)&r, sizeof(Book));
    int i = 1;
    while(!bf.eof())
    {
        if(i != n)
        {
            a.push_back(r);
        }
        ++i;
        bf.read((char*)&r, sizeof(Book));
    }
    bf.close();
    ofstream nbf;
    nbf.open(namebf, ios::binary);
    for(int i = 0; i < a.size(); ++i)
    {
        nbf.write((char*)&a[i], sizeof(Book));
    }
    nbf.close();
}
 
int OutBinFile(string namebf)
{
    fstream obf(namebf, ios::in | ios::binary);
    if(obf.is_open())
    {
        Book Bk;
        obf.read((char*)&Bk, sizeof(Bk));
        while(!obf.eof())
        {
            cout << Bk.Isbn << " " << Bk.Author << " " << Bk.Name << " " << Bk.Year << endl;
            obf.read((char*)&Bk, sizeof(Book));
        }
        obf.close();
        return 0;
    }
    return 1;
}
 
int main() {
    int kod = CreateBoolTxt("ab.txt", "Data.dat");
    if(kod == 0)
    {
        OutBinFile("Data.dat");
        cout << endl;
        int numRecord = PoiskISBNInBinFile("Data.dat", 10);
        cout << numRecord << endl;
        numRecord = PoiskAuthorInBinFile("Data.dat", 3);
        cout << numRecord << endl;
        NewFileBin("Data.dat", 1, "NewData.dat");
        OutBinFile("NewData.dat");
        cout << endl;
        DeleteBin("Data.dat", 3);
        OutBinFile("Data.dat");
        cout << endl;
    } else {
        cout << "error";
    }
    return 0;
}
Добавлено через 1 час 3 минуты
Цитата Сообщение от SmallEvil Посмотреть сообщение
std::ios::ate);
Такс. Это видимо и значит, что позиция в конец файла.

Цитата Сообщение от SmallEvil Посмотреть сообщение
std::size_t size = f.tellg();
А здесь мы видимо применяем такую фишку, что tellg выдает позицию курсора в непонятно каких единицах, но тем самым мы находим размер всего файла.

Цитата Сообщение от SmallEvil Посмотреть сообщение
Book b;
Это мы создаем объект структуры?

Цитата Сообщение от SmallEvil Посмотреть сообщение
f.seekg(sizeof(Book)*(2-1)); // переместились ко второй записи
        f.read((char*)&b, sizeof(Book));
А вот эти две записи хоть убейте, но до конца не понимаю. Мы типо выделяем память под размер структуры, а потом еще умножаем на (2-1)? Это что нам даёт?
И такая же ситуация с
C++
1
 f.read((char*)&b, sizeof(Book));
Как здесь работает char* и адрес b?
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
20.10.2022, 04:51
Цитата Сообщение от daniil_novel Посмотреть сообщение
А вот эти две записи хоть убейте, но до конца не понимаю.
Вы же сами так читаете данные.
Цитата Сообщение от daniil_novel Посмотреть сообщение
bf.read((char*)&Bk, sizeof(Book));
Цитата Сообщение от daniil_novel Посмотреть сообщение
Мы типо выделяем память под размер структуры, а потом еще умножаем на (2-1)? Это что нам даёт?
Мы определяем размер структуры, и умножаем на количество минус один.
Мы получаем смещение от начала файла к нужной записи.
seekg устанавливает позицию чтения.

Цитата Сообщение от daniil_novel Посмотреть сообщение
И такая же ситуация с
 f.read((char*)&b, sizeof(Book));
Как здесь работает char* и адрес b?
Берем адрес структуры, это же и начало блока данных.
Приводим к указателю на char(байт) и читаем столько байт сколько занимает структура sizeof(Book)

Добавлено через 2 минуты
Цитата Сообщение от daniil_novel Посмотреть сообщение
while(!bf.eof())
Такой способ не годится для проверки конца файла при чтении.
0
1 / 1 / 0
Регистрация: 19.03.2022
Сообщений: 99
20.10.2022, 08:54  [ТС]
Ааа. Теперь вроде даже всё встало на свои места. Спасибо большое)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.10.2022, 08:54

Работа с двоичными файлами
1. Постановка задачи Создать файл, содержащий числовые данные целого или вещественного типа и выполнить их обработку согласно заданному...

Работа с двоичными файлами
Всем привет.. пытаюсь понять один вопрос. допустим есть текстовый файл с таким содержанием я хочу эту информацию переписать в...

Работа с двоичными файлами
Создать файл и записать в него вещественные числа из диапазона от a до b с шагом h. Дана последовательность из n вещественных чисел....

Работа с двоичными файлами
Здравствуйте!!! Ребята подскажите по такому вопросу. Есть код который я набрал из учебника вот он: void __fastcall...

Работа с двоичными файлами
Создать файл,состоящий из n вещественных чисел. Вывести на экран все числа данного файла не попадающие в данный диапазон!!!


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

Или воспользуйтесь поиском по форуму:
24
Ответ Создать тему
Новые блоги и статьи
Оказывается, Unreal Engine позволяет качество на порядки выше, чем было в Lineedge
Etyuhibosecyu 05.07.2026
Жаль, конечно, что я не узнал об этом, пока Lineedge существовала, а то бы Noname2331 написал, что волки превращаются в пиксельную кашу, а я бы его попросил скачать какую-нибудь бриллиантовую или Pro. . .
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru