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

"Оптимизация" бинарного файла - C++

Восстановить пароль Регистрация
 
jayjay
0 / 0 / 0
Регистрация: 28.05.2012
Сообщений: 26
04.11.2012, 15:16     "Оптимизация" бинарного файла #1
Всем добрый день, и заранее спасибо за помощь тем, кто сможет это сделать или хотя бы попытается
Сначала текст задания:

Для хранения данных о планшетных сканерах описать структуру вида, описанного
в варианте 1.
Написать функцию, которая записывает данные о сканере из приведенной структуры
в требуемую позицию в бинарном файле. Структура файла: в первых двух
байтах размещается значение типа int, определяющее количество сделанных в
файл записей; далее без пропусков размещаются записи о сканерах. Запись может
осуществляться в любую позицию, причем если между вводимой записью и
последней (или началом файла) имеются пропуски, они заполняются нулями.
Написать функцию, которая «уплотняет» описанный выше бинарный файл путем
удаления из него записей, содержащих все пули.

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

А вот и проблема: эта самая функция "уплотнения" отказывается работать, хоть убей. Гугл и поиск по форуму не спасли.

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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#include "stdafx.h"
#include <conio.h>
#include <stdlib.h>
#include <memory.h>
 
struct scan_info {
    char model[25]; // наименование модели
    int price; // цена
    double x_size; // горизонтальный размер области сканирования
    double y__size; // вертикальный размер области сканирования
    int optr; // оптическое разрешение
    int grey; // число градаций серого
} scan;
 
int ShowMenu();
void CreateFile(); 
void PrintFromFile();
void OptimizeFile(); 
 
int ShowMenu() {
    char ch = '\0';
    puts("1 : Create a file"); 
    puts("2 : View a file");
    puts("3 : Optimize a file");
    puts("4 : Exit");
    ch = _getch(); 
    return atoi(&ch); 
}
 
int main() {
    while (1) {  
        switch( ShowMenu() ) {  
            case 1: CreateFile(); break;
            case 2: PrintFromFile(); break; 
            case 3: OptimizeFile(); break; 
            case 4: return 0; 
            default: break;
        }
    }
}
const int min_records = 6; //минимальное число записей для ввода (нулевые учитываются)
 
void PrintArray (scan_info* si, int count) //вывод записей на экран из массива
{
    for (int i = 0; i < count; i++)
        printf ("\n%i. %s price: %i grey: %i", i+1, si[i].model, si[i].price, si[i].grey);
}
 
void PrintFromFile () //вывод записей на экран из файла
{
    FILE* data;
    char* db = "file.bin";
    data = fopen (db, "rb"); //открываем файл
    if (!data) { //ошибка, если не открылся
        printf ("Error");
        return;
    }
    short count; //читаем количество записей
    int k = fread (&count, sizeof(short), 1, data);
    if (k != 1) { //ошибка, если считалось неверное количество данных
        printf ("Error");
        return;
    }
    scan_info* si = new scan_info[count]; //выделяем место под массив
    k = fread (si, sizeof(scan_info), count, data); //считываем массив
    if (k != count) {
        printf ("Error");
        return;
    }
    for (int i = 0; i < count; i++) //выводим на экран
        printf ("\n%i. %s price: %i grey: %i", i+1, si[i].model, si[i].price, si[i].grey);
    fclose (data);
}
 
 
void OptimizeFile () //сжатие записей из файла
{ 
    FILE* data;
    char* db = "file.bin";
    data = fopen (db, "r+b"); //открываем файл
    if (!data) { //ошибка, если не открылся
        printf ("Error");
        return;
    }
    short count; //читаем количество записей
    int k = fread (&count, sizeof(short), 1, data);
    if (k != 1) { //ошибка, если считалось неверное количество данных
        printf ("Error");
        return;
    }
    scan_info* si = new scan_info[count]; //выделяем место под массив
    k = fread (si, sizeof(scan_info), count, data); //считываем массив
    if (k != count) {
        printf ("Error");
        return;
    }
 
    PrintArray (si, count); //выводим на экран для контроля
    fseek (data, sizeof(short), SEEK_SET); //переходим в начало файла, пропуская число записей
 
    short newcount = 0; //число реальных записей
    scan_info nul; //нулевая запись для сравнения
    memset (&nul, 0, sizeof(nul)); //заполняем нулями
 
    for (int i = 0; i < count; i++) { //просмотриваем массив
        if (memcmp (&nul, &si[i], sizeof(scan_info)) != 0) { //Если запись не идентична нулевой
            k = fwrite (&si[i], sizeof(scan_info), 1, data); //пишем запись в файл
            if (k != 1)  {
                printf ("Error");
                return;
            }
            newcount++; //наращиваем реальное количество
        }
    }
 
    fseek (data, 0, SEEK_SET); //переходим в начало файла
    k = fwrite (&newcount, sizeof(short), 1, data); //пишем реальное количество записей
    if (k != 1)  {
        printf ("Error");
        return;
    }
    fclose (data); //закрываем файл
}
 
void CreateFile () //создание файла
{
    short n = 0; //количество записей
    int pos;
    scan_info si, nul;
    memset (&nul, 0, sizeof(nul)); //нулевая запись для пропусков заполняется нулями
    FILE* data;
    char* db = "file.bin";
    data = fopen (db, "wb");
    if (!data) {
        printf ("Error");
        return;
    }
    int k = fwrite (&n, sizeof(short), 1, data); //пока пишем 0 в файл
    if (k != 1) {
        printf ("Error");
        return;
    }
    char c = 'y'; //признак выхода из цикла
    while (c=='y') { //вводим записи
        printf ("\nInput new record.\nInput model:\n");
        scanf ("%s", &si.model);
        printf ("\nInput price:\n");
        scanf ("%d", &si.price);
        printf ("\nInput horizontal size:\n");
        scanf ("%f", &si.x_size);
        printf ("\nInput vertical size:\n");
        scanf ("%f", &si.y__size);
        printf ("\nInput optical resolution:\n");
        scanf ("%d", &si.optr);
        printf ("\nInput shade of grey:\n");
        scanf ("%d", &si.grey);
        printf ("\nInput position to save (-1 for write to the end):\n");
        scanf ("%d", &pos); //дополнительно спрашиваем позицию для сохранения
 
        n++; //наращиваем количество
        if (pos < 0) pos = n; //если ввели отрицательную позицию, пишем в конец файла
        if (pos > n) { //если позиция дальше текущей
            fseek (data, (n-1)* sizeof(si) + sizeof(short), SEEK_SET);
//переставляем указатель в файле на текущее место
            while (pos > n) { //пишем столько нулевых записей, сколько позиций надо пропустить
                fwrite (&nul, sizeof(nul), 1, data);
                n++;
            }
        } else if (pos < n) { //если позиция раньше текущей
            n--; //не считаем эту запись - она займёт имеющееся место
            fseek (data, (pos-1)* sizeof(si) + sizeof(short), SEEK_SET);
//ставим указатель на нужное место
        } else //пишем на текущую позицию, ставим на неё указатель
            fseek (data, (n-1)* sizeof(si) + sizeof(short), SEEK_SET);
        
 
        k = fwrite (&si, sizeof(si), 1, data); //пишем запись в файл
        if (k != 1) {
            printf ("Error");
            return;
        }
        if (n >= min_records) { //если 6 записей уже введено, то предлагаем прервать ввод
            printf ("\nPress 'y', if you want to continue, or any other key, if you don't\n");
            c = getch(); //если будет введён не у, то выйдем из цикла
        }
    }
 
    fseek (data, 0, SEEK_SET); //идём в начало файла
    k = fwrite (&n, sizeof(short), 1, data); //пишем реальное количество записей
    if (k != 1) {
        printf ("Error");
        return;
    }
    fclose (data); //закрываем файл
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.11.2012, 15:16     "Оптимизация" бинарного файла
Посмотрите здесь:

C++ "Рекурсивная функция" (Обход бинарного дерева)
C++ Определение класса, описывающего комплексное число. Перегрузка для него бинарного оператора "*"
C++ Считать с файла информацию о команде "Название" "Город", количество побед, поражений, ничьих, забитых и пропущенных мячей
C++ Подсчитать сумму "серых" элементов, а "черные" сложить только один раз
C++ Оптимизация кода "dll"
C++ Загрузка информации из файла (система рекордов в игре "Змейка")
ткните мордой плз на описание конструкций типа defect?"brak":"goden" C++
Из текстового файла прочитать в массивы пары "символ - число" C++
Считать строку из файла и удалить все парные буквы "w" C++
Оптимизация игры "Угадай число" C++
C++ Оптимизация игры "Однорукий бандит"
Удалить строку из файла, если имя начинается на букву "А" C++

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

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

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