Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,686
1

Есть структура, компилятор считывает некоторые её поля ТОЛЬКО из адресов, кратным двум, а их там нет! (полей), как быть?

06.03.2012, 13:30. Показов 713. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
То есть вот структура:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct TGAHEADER
{
         char   IdLength;
         char   ColourMapType;
         char   DataTypeCode;
         WORD    ColourMapOrigin;
         WORD    ColourMapLength;
         char   ColourMapDepth;
         WORD    x_Origin;
         WORD    y_Origin;
         WORD    Width;
         WORD    Height;
         char   BitsPerPixel;
         char   ImageDescriptor;
};
TGAHEADER tgaheader;
 
//И она располагается в каком-то файле Fire.tag, вот я её считал:
fread(&tgaHeader, 1/* sizeof(TGAHEADER)*/, 18, pFile);
Теперь как обратиться к полю BitsPerPixel? Вот так не обратиться!
C++
1
tgaHeader.BitsPerPixel
А потому, что предыдущее поле ColourMapOrigin считьывается не по смещению 3, где оно есть, а по смещению 4. НАверное, потому что word. Соттветственно и последующие поля считываются не оттуда, где они находятся, а с других адресов

Ну я извращаюсь щас всяко, так например:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct TGAHEADER
{
         char   IdLength;
         char   ColourMapType;
         char   DataTypeCode;
         
         //Если понадобится один из пяти байтов, опять придётся извращаться
         char x [5];
 
         WORD    x_Origin;
         WORD    y_Origin;
         WORD    Width;
         WORD    Height;
         char   BitsPerPixel;
         char   ImageDescriptor;
};
Можно так ещё:
C++
1
*((char*)&tgaHeader+ 16;
Но это костыли какие-то, есть грамотный способ? Спасибо, кто откликнется!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.03.2012, 13:30
Ответы с готовыми решениями:

Как проверить запись на существование и добавить ее в базу данных если ее там нет или отредактировать если она там есть?
INSERT INTO AdvancedAccess...

Вернуть номер позиции заданного символа в строке, если он там есть, и 0, его там нет
Доброго времени суток! Помогите решить задание на с# (тема: Методы. Рекурсивные методы): Написать...


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

Или воспользуйтесь поиском по форуму:
6
31 / 31 / 6
Регистрация: 15.12.2011
Сообщений: 108
06.03.2012, 14:39 2
записать нужно так

fwrite(&tgaheader, sizeof(tgaheader));

а считать fread(&tgaheader, sizeof(tgaheader));

но луче всего создать функцию записи/сохранения, которая бы записывала/считывала каждый член структуры в отдельности.
1
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
06.03.2012, 15:48 3
Читай про выравнивание.
Можешь обернуть свою структуру в прагмы (они могут отличаться в твоем компиляторе, RTFM документацию на него):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma pack(push, 1)
struct TGAHEADER {
          char   IdLength;
          char   ColourMapType;
          char   DataTypeCode;
          WORD    ColourMapOrigin;
          WORD    ColourMapLength;
          char   ColourMapDepth;
          WORD    x_Origin;
          WORD    y_Origin;
          WORD    Width;
          WORD    Height;
          char   BitsPerPixel;
          char   ImageDescriptor;
};
#pragma pack(pop)

1
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,686
07.03.2012, 00:41  [ТС] 4
CheshireCat, спасибо, помогло
C++
1
2
         WORD    ColourMapOrigin __attribute__ ((packed));
         WORD    ColourMapLength __attribute__ ((packed));
0
Псевдослучайный
1946 / 1145 / 98
Регистрация: 13.09.2011
Сообщений: 3,215
07.03.2012, 00:43 5
kravam, внимание вопрос: зачем тебе это? Выравнивание компилятор не чисто поржать делал.
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,686
07.03.2012, 00:53  [ТС] 6
Чтобы можно было обращаться к полю структуры
C++
1
tgaHeader.BitsPerPixel
+++++++++++++++++++++++++++++++++

И да, а зачем он выравнивает? Наверное, чтобы прога побыстрее работала, но в моём случае это некритично. Была бы какая другая причина- наверное, он бы не скомпилил код, не?

Добавлено через 6 минут
И кстати, сразу же договорися о терминах- при считывании из файла в структуру компилятор НЕ ВЫРАВНИВАЕТ, он перегоняет содержимое структуры КАК ЕСТЬ.
Но вот при считывании из этого участка памяти программа считает, что все поля выровнены.
0
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
07.03.2012, 01:20 7
Шилдт описывал такую вещь как указатель на поле структуры, может пригодится:
C++
1
2
3
4
5
    TGAHEADER tgah;
    tgah.BitsPerPixel = 'X';
    char TGAHEADER::*bpp;           // объявляем указатель на член класса
    bpp = &TGAHEADER::BitsPerPixel; // Определяем смещение BitsPerPixel
    cout << tgah.*bpp << endl;
0
07.03.2012, 01:20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru