Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Cepairda
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 10
#1

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

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

Формат файла состоит из 3 структур и одной переменной. Подробное описание формата во вложении, просьба посмотреть его. У меня возникла проблема, я не знаю как его читать. Дело в то что начало 5 байт - Идентификатор
Файла-карты для программразличных версий. Дальше идет структура - 32 байта, дальше переменная 4 байта, дальше опять идет структура, она может быть одна, а может и 100 штук - размер одной 47 байт, далее идет следующая структура, ее размер 614 байт, она также может быть одна или несколько, как читать этот бинарный файл не пойму. Подробности структуры и т.д. в файле, который находится в приложении.
http://www.cyberforum.ru/cpp-beginners/thread1335580.html
0
Вложения
Тип файла: doc Формат ЭК(файлы map).doc (56.0 Кб, 8 просмотров)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.02.2016, 12:26
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Чтение нескольких структур и одной переменной из бинарного файла. Формат файла имеется (C++):

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

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

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

Заполнение динамического массива структур из бинарного файла
Здравствуйте! Нужна помощь в реализации вот такого алгоритма: предположим,...

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

16
basileus
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 27
14.02.2016, 12:55 #2
Вы не знаете как читать бинарный файл с определённого места? Установить позицию, пользуясь функцией lseek().
0
Cepairda
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 10
14.02.2016, 13:16  [ТС] #3
Прочитайте внимательно мою тему. Как мне понять по сколько считывать структуры ? Может быть так:
5 + 32 + 4 + 47, может быть 5 + 32 + 4 + 47 + 614, может быть 5 + 32 + 4 + 47 + 47 + 47 + 47 + 614 + 614. И как понять где закончилась одна структура, а где началась другая ?
0
basileus
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 27
14.02.2016, 14:07 #4
CountKm: word {количесво существующих 500-метровых участков путей}
-как я понимаю, число структур по 47 байт. Далее (c Pos2) идут 614 байтные. Разве не так?
0
Cepairda
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 10
14.02.2016, 14:20  [ТС] #5
Нет, с начало идет 5 байт - Идентификатор Файла-карты для программ различных версий, далее идет 32 байта - Заголовок файла-карты и резервная область, затем идет 4 байта Pos2, затем 47 байт(структура, может быть несколько,каждые 500 метров это 47 байт), а затем 614 байт(структура, может быть несколько)
0
basileus
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 27
14.02.2016, 14:27 #6
5+32+4 -постоянно присутствующие части. В них содержится информация, сколько будет блоков по 47, сразу за этим большим заголовком, и с какой позиции начинаются списки из 614 байтных структур. Где трудность?
0
Cepairda
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 10
14.02.2016, 15:22  [ТС] #7
Так немного понимать начинаю. Получаем структуру, где 32 байта, и получаем число блоков по 47 байтов, я так понял. А получить начало структуры по 614 как ? Это в Pos2 написано ? Можешь пожалуйста помочь разобрать файл небольшой, я описал вроде структуры все на С++, но как разобрать еще не понимаю до конца, задали на практике, завтра нужно показать результат, а у меня ничего пока что, могли бы в скайпе связаться и т.д., хочется разобраться
0
basileus
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 27
14.02.2016, 16:18 #8
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
basileus
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 27
14.02.2016, 17:51 #9
Я не хочу общаться напрямую. Что еще вам подсказать?
стр. 66, 77 - выделяем память либо под один чанк, либо под весь набор. (смнеить 1 на закоменченое в скобках)
стр. 69, 80 - обрабатываем очередной чанк, (соответственно, меняем индекс, если вычитываем весь набор.)
структуры доописать, с этим проблем быть не должно.
//just do it!! - меняем на ваш обработчик чанка.
0
Cepairda
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 10
14.02.2016, 19:12  [ТС] #10
Изменить формат на .map. Попробуйте его разобрать
0
Вложения
Тип файла: doc EmptyMap.doc (135 байт, 3 просмотров)
Cepairda
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 10
14.02.2016, 22:55  [ТС] #11
Получилось что-то ?
0
basileus
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 27
14.02.2016, 23:10 #12
А вы сами-то попробовали?
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
Cepairda
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 10
14.02.2016, 23:19  [ТС] #13
Тот файл, что я скинул, в нем вообще нет структуры в 614 байт. В нем 135 байт = 5 + 32 + 4 + 47 + 47. Может быть и такой случай, что 614 байт не будет.
0
basileus
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 27
14.02.2016, 23:22 #14
со 165 по 171 строчку вывод дополнительной информации, и в ней размер описанной 614 байтной структуры = 610.
Нестыковка, однако.
0
Cepairda
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 10
14.02.2016, 23:53  [ТС] #15
А как ее можно вообще считать, если ее в файле просто напросто нет вообще

Файл *.map представляет собой бинарный файл, в котором содержится информация, представленная ниже. Формат файла предполагает разбиение всех километровых участков, разделенных на 500-метровые участки (тип записи zagkm). Например, при создании электронной карты, состоящей из одного 1-км участка, в файле *.map будут присутствовать две записи zagkm. Если данная электронная карта не будет содержать никаких объектов, то запись InfoFile будет отсутствовать. Соответственно, минимально возможный объем электронной карты может составить 135 байт (5+32+4+47*2). При добавлении очередного 1-км участка объем файла будет увеличиваться на 94 байта (47*2). При добавлении на карту нового объекта (запись InfoFile) объем файла будет увеличиваться на 614 байт.
0
basileus
1 / 1 / 2
Регистрация: 25.05.2015
Сообщений: 27
15.02.2016, 00:03 #16
Еще раз.
Цитата Сообщение от Cepairda Посмотреть сообщение
Можешь пожалуйста помочь разобрать файл небольшой, я описал вроде структуры все на С++,
Я привёл код, где описана структура, заявленная в приложенном вами файле имеющая размер 614 байт.
Описанную в коде структуру компилятор считает имеющей размер 610 байт. Вы не видите здесь некоторой нестыковки, могущей иметь серьёзное воздействия на корректность работы программы?
Может, следует разобраться с этим? И кстати, минимально возможный размер может быть 5+32+4, разве не так?
0
Cepairda
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 10
15.02.2016, 00:51  [ТС] #17
Нет, минимальный 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
15.02.2016, 00:51
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.02.2016, 00:51
Привет! Вот еще темы с решениями:

Чтение из бинарного файла
Здравствуйте. У меня имеется некий класс Product, объекты которого хранятся в...

Чтение бинарного файла
Добрый Добавлено через 6 минут Добрый день. Не получается прочитать бин....

Чтение из бинарного файла
Уважаемые форумчане! Прошу помочь мне с чтением из бинарного файла. Проблема...

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


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

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

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