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

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

19.10.2022, 23:28. Показов 2256. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru