Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » запись структур в VС++

Ответить
Настройки темы
запись структур в VС++

Новый участник


Сообщения: 29
Благодарности: 0

Профиль | Отправить PM | Цитировать


Проблема в следующем, есть bmp, gif или любой другой файл и мне нужно его прочитать. Для начала надо прочитать заголовок, который представлен в виде структуры. Но он читается не правильно, из-за “word alignment”, т.е. то, что меньше 4байт увеличивается до 4, что сами понимаете, в данном случае критично. Как убрать это выравнивание? (программа – Win32 Console Application)

Отправлено: 20:11, 14-02-2004

 

Пользователь


Сообщения: 135
Благодарности: 0

Профиль | Отправить PM | Цитировать


Я как-то писал утилитку(в учебных целях) которая табуляцию заменяеи пробелами. С параметром 2, 4 или 8 пробела на табуляцию. Удобно для некоторых исходников. Но не в этом дело.
Первый вариант был что-то вроде вашего (fputc fgetc)
Второй я читал блоками, размером 0x8000
Так вот второй вариант раз в 100 быстрее оказался.
На больших файлах весьма заметно.
Да и диск жалко дергать взад вперед. (Еслиб небыло кеширования то он быстро бы загнуля )
А размер файла не имеет значения. Хоть Гигабайт.

Отправлено: 02:41, 28-02-2004 | #11



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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


Новый участник


Сообщения: 29
Благодарности: 0

Профиль | Отправить PM | Цитировать


ладно, это я переделаю на чтение блоками, а какого размера надо блоки брать?

Отправлено: 16:59, 28-02-2004 | #12


Пользователь


Сообщения: 135
Благодарности: 0

Профиль | Отправить PM | Цитировать


Drey
Размер ровное (двоичное) какое-нибудь число, лучше если кратное размеру кластера минимально это 512 байт.
А так исходи из собственных ресурсов 32K (0x8000) например неплохо.

Ну и раз пошла такая пьянка, еще пару слов.
По поводу первого твоего вопроса
#pragma pack(1) - Это конечно хорошо, но не портабельно.
Если ты делаешь программку для одной платформы с интеловсим процем, то так конечно проще всего.
Но если твой код будет компилироваться под другие платформы (процесоры), то там возможны засады.
Интеловские процы пишут младший байт сначала, на других системах возможно все будет наоборот, и тогда твои (bmp, gif) будут не валидными.

Отправлено: 02:17, 01-03-2004 | #13


Новый участник


Сообщения: 29
Благодарности: 0

Профиль | Отправить PM | Цитировать


bilytur, да, я читал на MSDN про эту фишку и там говориться, что лучше использовать ключевые слова, только есть одно "но" - они не воспринимаются компилятором, т.е. он говорит, что данная версия это не поддерживает.
Ладно, если #pragma pack(1) это не то, то что же тогда то? как это исправить?
Причем надо читать отдельно заголовок и отдельно содержимое - это приниципиально.


[s]Исправлено: Prisoner, 0:24 2-03-2004[/s]

Отправлено: 15:02, 01-03-2004 | #14


редкий гость


Сообщения: 1696
Благодарности: 44

Профиль | Сайт | Отправить PM | Цитировать


Читай/пиши побайтово (можно, что бы побыстрей, в буффер весь заголвок, а из него побайтово "расфасовывать". Тогда не будет проблем с переносимостью между big/little-endian арзитектурами, с выравниванием проблем тоже не будет. По-моему, все портабельные программы работающие с бинарными данными делают именно так.

-------
http://ivank.ru


Отправлено: 16:54, 01-03-2004 | #15


Пользователь


Сообщения: 135
Благодарности: 0

Профиль | Отправить PM | Цитировать


Ну ivank Как всегда прав.
Вот небольшой пример.
Две функции для чтения и записи 32-разрядного целого.
Код: Выделить весь код
__int32 ReadINT(void* pS)
{
  unsigned char* p = (unsigned char*)pS;
  __int32 res = p[3];
  res = (res<<8) | p[2];
  res = (res<<8) | p[1];
  res = (res<<8) | p[0];
  return  res;
}

void WriteINT(__int32 V, void* pD)
{
  unsigned char* p = (unsigned char*)pD;
  *p++ = V; V>>=8;
  *p++ = V; V>>=8;
  *p++ = V; V>>=8;
  *p   = V;
}
Как использовать. Пример:
Например по смещению 38 надо считать число, прибавить 5 и записать назад.
Код: Выделить весь код
char Buf[SIZE]; // Это твой буфер

int a = ReadINT(&Buf[38]);
a += 5;
WriteINT(a, &Buf[38]);
А вообще если тебе действительно не нужна портабельность то не заморачивайся с этим.

Отправлено: 02:23, 02-03-2004 | #16


Новый участник


Сообщения: 29
Благодарности: 0

Профиль | Отправить PM | Цитировать


прикольный код... правда я не понял, что он делает??? если p - указательна char, то после одного смещения на 8 бит он должен тихо сканчаться...
и, как я понял из вышесакзанного надо правильнее
char Buf[512];
int a = ReadINT(&Buf)

Отправлено: 17:17, 02-03-2004 | #17


Пользователь


Сообщения: 135
Благодарности: 0

Профиль | Отправить PM | Цитировать


Код правильный, даже синтаксических ошибок нет.
Цитата:
программа – Win32 Console Application
Если пишешь под виндоус то используй #pragma pack(push, 1)
И живи спокойно. Портабельность тебе судя по всему не грозит.

Отправлено: 02:27, 03-03-2004 | #18



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » запись структур в VС++

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
.NET - [решено] C# to C++ dll: Маршалинг(?) массива структур XCodeR Программирование и базы данных 4 22-01-2010 10:18
[решено] Отключенная учетная запись и запись с истекшим сроком действия. В чем разница? CaminoDeFlores Microsoft Windows NT/2000/2003 4 01-06-2009 09:30
C/C++ - Сравнение структур в языке 'С' t0lkman Программирование и базы данных 1 21-04-2008 14:30
Запись на CD Bahram_aka Автоматическая установка Windows 2000/XP/2003 2 31-01-2007 02:47
Запись на CD Arex Программное обеспечение Windows 14 03-03-2002 17:03




 
Переход