Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/18: Рейтинг темы: голосов - 18, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 14.02.2016
Сообщений: 10

Чтение нескольких структур и одной переменной из бинарного файла. Формат файла имеется

14.02.2016, 12:26. Показов 4001. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Формат файла состоит из 3 структур и одной переменной. Подробное описание формата во вложении, просьба посмотреть его. У меня возникла проблема, я не знаю как его читать. Дело в то что начало 5 байт - Идентификатор
Файла-карты для программразличных версий. Дальше идет структура - 32 байта, дальше переменная 4 байта, дальше опять идет структура, она может быть одна, а может и 100 штук - размер одной 47 байт, далее идет следующая структура, ее размер 614 байт, она также может быть одна или несколько, как читать этот бинарный файл не пойму. Подробности структуры и т.д. в файле, который находится в приложении.
Вложения
Тип файла: doc Формат ЭК(файлы map).doc (56.0 Кб, 15 просмотров)
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.02.2016, 12:26
Ответы с готовыми решениями:

Чтение вектора структур из бинарного файла
Есть функция записи и чтения: void fout(vector<struc>&arr, string path) { int a, b; ofstream fl(path, ios::binary); ...

Чтение массива структур из бинарного файла
Доброго времени суток.Возникла проблема с чтением структур из бинарного файла.Файл открывает,но при считывании данных, сразу закрывается с...

Чтение массива структур из бинарного файла
при выводе дает какую-то кашу из символов переписываю структуру из одного файла в 10. это необходимо для внешней сортировки слиянием ...

16
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 33
14.02.2016, 12:55
Вы не знаете как читать бинарный файл с определённого места? Установить позицию, пользуясь функцией lseek().
0
0 / 0 / 0
Регистрация: 14.02.2016
Сообщений: 10
14.02.2016, 13:16  [ТС]
Прочитайте внимательно мою тему. Как мне понять по сколько считывать структуры ? Может быть так:
5 + 32 + 4 + 47, может быть 5 + 32 + 4 + 47 + 614, может быть 5 + 32 + 4 + 47 + 47 + 47 + 47 + 614 + 614. И как понять где закончилась одна структура, а где началась другая ?
0
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 33
14.02.2016, 14:07
CountKm: word {количесво существующих 500-метровых участков путей}
-как я понимаю, число структур по 47 байт. Далее (c Pos2) идут 614 байтные. Разве не так?
0
0 / 0 / 0
Регистрация: 14.02.2016
Сообщений: 10
14.02.2016, 14:20  [ТС]
Нет, с начало идет 5 байт - Идентификатор Файла-карты для программ различных версий, далее идет 32 байта - Заголовок файла-карты и резервная область, затем идет 4 байта Pos2, затем 47 байт(структура, может быть несколько,каждые 500 метров это 47 байт), а затем 614 байт(структура, может быть несколько)
0
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 33
14.02.2016, 14:27
5+32+4 -постоянно присутствующие части. В них содержится информация, сколько будет блоков по 47, сразу за этим большим заголовком, и с какой позиции начинаются списки из 614 байтных структур. Где трудность?
0
0 / 0 / 0
Регистрация: 14.02.2016
Сообщений: 10
14.02.2016, 15:22  [ТС]
Так немного понимать начинаю. Получаем структуру, где 32 байта, и получаем число блоков по 47 байтов, я так понял. А получить начало структуры по 614 как ? Это в Pos2 написано ? Можешь пожалуйста помочь разобрать файл небольшой, я описал вроде структуры все на С++, но как разобрать еще не понимаю до конца, задали на практике, завтра нужно показать результат, а у меня ничего пока что, могли бы в скайпе связаться и т.д., хочется разобраться
0
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 33
14.02.2016, 16:18
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
/* roadway file reader
 *
 *
*/
#include <iostream>     // std::cout
#include <fstream>      // std::ifstream
 
using namespace std;
typedef unsigned char byte;
typedef   unsigned  Cardinal;
typedef   unsigned char byte;
typedef   unsigned  short word;
typedef   long LongInt;
struct TypeFile
{
    byte ByteC;
    byte ByteN;
    byte ByteS;
    byte ByteT;
    byte Byte2;
};
 
struct  Zagolov
{
    Cardinal Naprav;
    Cardinal Sdvig;
    byte ShiftLat;
    byte ShiftLong;
    word CountKm;
//    byte Rezerv[20];
};
 
struct InfoFile //614 chunk
{
    LongInt LinAddr;
    ///others
};
 
struct zagkm
{
    Cardinal LinCoord;
    LongInt geosh;
    LongInt geodl;
    /// - others
};
    Zagolov zagolov;
    int Pos2;
    zagkm* chunk47;
    InfoFile* chunk614;
 const int zagkmBegin = sizeof(TypeFile) + sizeof(Zagolov) + sizeof(Pos2); 
 
int main () {
  ifstream is ("test.map", ifstream::binary);
  if (is) {
    // get length of file:
    is.seekg (0, is.end);
    int length = is.tellg();
    is.seekg (0, is.beg);
    //
    is.seekg (sizeof(TypeFile), is.beg);
    is.read( reinterpret_cast<char *>(&zagolov), sizeof(zagolov));
    is.read( reinterpret_cast<char *>(&Pos2), sizeof(Pos2));
    
    is.seekg (zagkmBegin, is.beg);
    
    zagkm* chunk47= new zagkm[1/*zagolov.CountKm*/]; // up to you!!!
    for(int i=0;i< zagolov.CountKm; i++)
    {
        is.read( reinterpret_cast<char *>(&chunk47[0/*i */]), sizeof(zagolov)); //up to you!!!
        //just do it
        //...
    }
 
    
     is.seekg (Pos2, is.beg);
    int InfoFileCount = (length - zagkmBegin - zagolov.CountKm*sizeof(zagkm) ) / sizeof(InfoFile);
    InfoFile * chunk614 = new InfoFile[1/*InfoFileCount */]; // up to you!!!
    for(int i = 0;i < InfoFileCount; i++)
    {
        is.read( reinterpret_cast<char *>(&chunk614[0/*i */]), sizeof(zagolov)); //up to you!!!
        //just do it
        //...
    }
 
 
    is.close();
 
    delete[] chunk47;
    delete[] chunk614;
 
    }
 
  return 0;
}
как-то так
0
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 33
14.02.2016, 17:51
Я не хочу общаться напрямую. Что еще вам подсказать?
стр. 66, 77 - выделяем память либо под один чанк, либо под весь набор. (смнеить 1 на закоменченое в скобках)
стр. 69, 80 - обрабатываем очередной чанк, (соответственно, меняем индекс, если вычитываем весь набор.)
структуры доописать, с этим проблем быть не должно.
//just do it!! - меняем на ваш обработчик чанка.
0
0 / 0 / 0
Регистрация: 14.02.2016
Сообщений: 10
14.02.2016, 19:12  [ТС]
Изменить формат на .map. Попробуйте его разобрать
Вложения
Тип файла: doc EmptyMap.doc (135 байт, 5 просмотров)
0
0 / 0 / 0
Регистрация: 14.02.2016
Сообщений: 10
14.02.2016, 22:55  [ТС]
Получилось что-то ?
0
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 33
14.02.2016, 23:10
А вы сами-то попробовали?
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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/* roadway file reader
 *
 *
*/
#include <iostream>     // std::cout
#include <fstream>      // std::ifstream
 
using namespace std;
typedef unsigned char byte;
typedef   unsigned  Cardinal;
typedef   unsigned char byte;
typedef   unsigned  short word;
typedef   bool boolean;
typedef   long LongInt;
 
#pragma pack (push,1)
struct Cod
{
unsigned char WayPointType:2;
//разряды 1-0 – признак «Начало/конец участка»:
//«0» - середина участка,
//«1» - начало участка,
//«2» - конец участка
unsigned char ChannelNum:2;
//разряды 5-2 – код частоты радиоканала
unsigned char isCrossRoad:1;
//разряд 6 – признак скрещивания участков «Перекресток»:
//«0» - отсутствует скрещивание,
//«1» - участки скрещиваются.
unsigned char CoordChanged:1;
//разряд 7 – признак «Изменение координаты»:
//«0» - возрастание орд-ты по нечетным путям,
//«1» - возрастание орд-ты по четным путям.
 
};
//#pragma pack (pop)
 
struct Saut
{
 
};
struct SAut
{
word width:15;
word SwitchType:1;
/*    
разряд 15 - для объекта  «Проба тормозов» - тип пробы:
            «0» - АТ; «1» - ЭПТ.
- для объекта «Светофор» - признак усл.-разреш:
   «0» - нет;  «1» - да.
- для объекта «Станция» - признак наличия РК:
  «0» - нет; «1» - есть.
- для объекта «ГПУ САУТ» - ст.бит типа ГПУ:
  (см. расшифровку мл.бита типа ГПУ).
разряд 14 - для объекта  «Проба тормозов» -вид пробы:
           «0» - основной; «1» - резервный.
- для объекта «Светофор» - признак подтяга:
  «0» - нет;  «1» - разрешен.
разряд 13 – признак скорости от АЛС-ЕН: «0» -нет АЛС-ЕН, «1» - есть скорость от АЛС-ЕН}
разряд 12 – для объекта «Светофор» - признак подтяга для  
                     длинносоставных грузовых поездов:
                   «0» - нет;  «1» - разрешен.
*/
};
 
struct SAut2
{
 unsigned char SwitchType:2;
/*     для объекта «ГПУ САУТ»:
 разряд 15 – мл.бит типа ГПУ:
«0» - предвходной; «1» - вх./маршр, «2» - выходной.
                                                 разряды 14-11 – номер ГПУ.
 разряды 10-0 – номер перегона}
*/
};
 
struct TypeFile
{
    byte ByteC;
    byte ByteN;
    byte ByteS;
    byte ByteT;
    byte Byte2;
};
 
struct  Zagolov
{
    Cardinal Naprav;
    Cardinal Sdvig;
    byte ShiftLat;
    byte ShiftLong;
    word CountKm;
    byte Rezerv[20];
};
 
struct InfoFile //614 chunk
{
    
    LongInt LinAddr;//LinAddr: LongInt      {линейная координата объекта}
    byte Tip;//Tip: byte            {тип объекта: см. таблицу ниже по тексту}
    byte Road;//Road: byte          {путь, которому принадлежит объект}
    char Nazvanie[8];//Nazvanie: array[1..8] of char   {название (имя) объекта}
    union SGreen
    {//SGreen: word {биты 0..15,
    word sizer;
    SAut Saut;
    };
 
    byte SYellow;//SYellow: byte
    /*{допустимая скорость проезда препятствия. Для объекта  «Проба тормозов» - скорость начала торможения}*/
    byte Uklon;//Uklon: byte    {значение несущей частоты АЛСН}
    word Width;//Width: word    {длина объекта. Для объекта  «Проба тормозов» - расчетный тормозной путь}
    union Uklon2
    {//Uklon2: word         
    word sizer;
    //    Lighter lighter;
    SAut2 Saut2;
    /*{для объекта «Светофор» - приведенный к б/у уклон пути,
        для объекта «ГПУ САУТ»:
        разряд 15 – мл.бит типа ГПУ:
        «0» - предвходной; «1» - вх./маршр, «2» - выходной.
                                                 разряды 14-11 – номер ГПУ.
        разряды 10-0 – номер перегона}
    */
    };
word En_Speed[6][49];
//En_Speed: array [1..6,1..49]of word; массив ограничений скорости движения по новой таблице АЛС-ЕН.
LongInt Id;//Id: LongInt            {относительный указатель на другой объект 500-м участка}
//абсолютный адрес объектов = Pos2 + Id.
//Если Id=-1, тогда у 500-метрового участка больше нет  объектов  }
 
};
 
struct zagkm
{
    Cardinal LinCoord;
    LongInt geosh;
    LongInt geodl;
    boolean Enabled[30];
    LongInt ID;
    Cod Cod_;
};
#pragma pack (pop)
 
    Zagolov zagolov;
    int Pos2;
    zagkm* chunk47;
    InfoFile* chunk614;
 const int zagkmBegin = sizeof(TypeFile) + sizeof(Zagolov) + sizeof(Pos2); 
 
int main () {
  ifstream is ("test.map", ifstream::binary);
  if (is) {
    // get length of file:
    is.seekg (0, is.end);
    int length = is.tellg();
    is.seekg (0, is.beg);
    //
    is.seekg (sizeof(TypeFile), is.beg);
    is.read( reinterpret_cast<char *>(&zagolov), sizeof(zagolov));
    is.read( reinterpret_cast<char *>(&Pos2), sizeof(Pos2));
 
    int InfoFileCount = (length - zagkmBegin - zagolov.CountKm*sizeof(zagkm) ) / sizeof(InfoFile);
    int  checker = zagkmBegin + zagolov.CountKm*sizeof(zagkm);
    cout << "sizeof(zagkm)=" << sizeof(zagkm) << endl;
    cout << "sizeof(InfoFile)=" << sizeof(InfoFile) << endl;
    cout << "Pos2=" << Pos2 << endl; 
    cout << "zagolov.CountKm=" << zagolov.CountKm << endl;    
    cout << "checker=" << checker << endl; 
    cout << "length=" << length << endl; 
    cout << "InfoFileCount=" << InfoFileCount << endl;
 
    is.seekg (zagkmBegin, is.beg);
    
    zagkm* chunk47= new zagkm[1/*zagolov.CountKm*/]; // up to you!!!
    for(int i=0;i< zagolov.CountKm; i++)
    {
        is.read( reinterpret_cast<char *>(&chunk47[0/*i */]), sizeof(zagolov)); //up to you!!!
        //just do it
        //...
        cout<<"zagkm[" << i << "]={\n";
        cout<<"LinCoord="<<(LongInt) chunk47->LinCoord<<";\n";
        cout<<"geosh="<<(LongInt) chunk47->geosh<<";\n";
        cout<<"geodl="<<(LongInt) chunk47->geodl<<";\n";
        cout<<"//Enabled[30];\n";
        cout<<"ID="<<chunk47->ID<<";\n";
        cout<<"//Cod_;\n";
        cout<<"};\n";
    }
 
    
     is.seekg (Pos2, is.beg);
 
    InfoFile * chunk614 = new InfoFile[1/*InfoFileCount */]; // up to you!!!
    for(int i = 0;i < InfoFileCount; i++)
    {
        is.read( reinterpret_cast<char *>(&chunk614[0/*i */]), sizeof(zagolov)); //up to you!!!
        //just do it
        //...
    }
 
 
    is.close();
 
    delete[] chunk47;
    delete[] chunk614;
 
    }
 
  return 0;
}
614 не равен 610 - ищите ошибку в описании и реализации сами.
0
0 / 0 / 0
Регистрация: 14.02.2016
Сообщений: 10
14.02.2016, 23:19  [ТС]
Тот файл, что я скинул, в нем вообще нет структуры в 614 байт. В нем 135 байт = 5 + 32 + 4 + 47 + 47. Может быть и такой случай, что 614 байт не будет.
0
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 33
14.02.2016, 23:22
со 165 по 171 строчку вывод дополнительной информации, и в ней размер описанной 614 байтной структуры = 610.
Нестыковка, однако.
0
0 / 0 / 0
Регистрация: 14.02.2016
Сообщений: 10
14.02.2016, 23:53  [ТС]
А как ее можно вообще считать, если ее в файле просто напросто нет вообще

Файл *.map представляет собой бинарный файл, в котором содержится информация, представленная ниже. Формат файла предполагает разбиение всех километровых участков, разделенных на 500-метровые участки (тип записи zagkm). Например, при создании электронной карты, состоящей из одного 1-км участка, в файле *.map будут присутствовать две записи zagkm. Если данная электронная карта не будет содержать никаких объектов, то запись InfoFile будет отсутствовать. Соответственно, минимально возможный объем электронной карты может составить 135 байт (5+32+4+47*2). При добавлении очередного 1-км участка объем файла будет увеличиваться на 94 байта (47*2). При добавлении на карту нового объекта (запись InfoFile) объем файла будет увеличиваться на 614 байт.
0
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 33
15.02.2016, 00:03
Еще раз.
Цитата Сообщение от Cepairda Посмотреть сообщение
Можешь пожалуйста помочь разобрать файл небольшой, я описал вроде структуры все на С++,
Я привёл код, где описана структура, заявленная в приложенном вами файле имеющая размер 614 байт.
Описанную в коде структуру компилятор считает имеющей размер 610 байт. Вы не видите здесь некоторой нестыковки, могущей иметь серьёзное воздействия на корректность работы программы?
Может, следует разобраться с этим? И кстати, минимально возможный размер может быть 5+32+4, разве не так?
0
0 / 0 / 0
Регистрация: 14.02.2016
Сообщений: 10
15.02.2016, 00:51  [ТС]
Нет, минимальный 5+32+4+47

Добавлено через 16 минут
Я думаю у вас где-то ошибка вышла, смотрите
LinAddr: LongInt 4 байта
Tip: byte 1 байт
Road: byte 1 байт
Nazvanie: array[1..8] of char 8 байт
SGreen: word 2 байта
SYellow: byte 1 байт
Uklon: byte 1 байт
Width: word 2 байта
Uklon2: word 2 байта
En_Speed: array [1..6,1..49] 588 байт
Id: LongInt 4 байта

Вот и получается 4 + 1 + 1 + 8 + 2 + 1 + 1 + 2 + 2 + 588 + 4 = 614 байт

Добавлено через 30 минут
Кстати, в компиляторе показывает 614 байт, вы не правильно определили структуру.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.02.2016, 00:51
Помогаю со студенческими работами здесь

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

Как сделать чтение определенной переменной из бинарного файла
как сделать чтение определенной переменной из бинарного файла public void Load() { ListPlane.Clear(); ...

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

Запись из бинарного файла, в массив структур
Имеется бинарный файл, в него записан массив структур.Как мне произвести запись из файла в массив?

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


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru