![]() |
|
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]()
|
|
| unreg |
|
|||
|
Unregistered |
Столкнулся вот с такой интересной штукой: нужно читать данные из файла, у меня есть описание формата этого файла. Первая структура которая в него пишется выглядит примерно так:
имя тип длина ---------------------------- time time_t 4 байта Vmax int 2 байта Smax int 2 байта FR float 4 байта (типы данных из Си) по этому описанию я создал свою структуру: TStruct = record time: cardinal; Vmax:word; Smax:word; FR: single; (потому, что этот тип занимает 4 байта и представляет число с плавающей точкой) далее через TFileStream считываю эту структуру. Первые три поля заполняются правильными значениями, а последнее совсем не тем чем надо. Тогда вместо Single ставлю array [0..3] of byte и опять считываю. далее, значение поля FR преобразую так: AValue:=Single(Struct.FR) и получаю правильное значение. Как это объяснить? Почему я не могу сразу считать в переменную типа Single и мне нужно действовать через массив? |
|||
|
||||
| ~FoX~ |
|
|||
![]() НЕ рыжий!!! ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2819 Регистрация: 8.10.2003 Где: Зеленоград Репутация: 13 Всего: 68 |
Single весит 2 байта.
Используй Real. Добавлено @ 09:57 Заранее извеняюсь. мог и напутать |
|||
|
||||
| Guest |
|
|||
|
Unregistered |
Что, собственно, и сделал. :-) |
|||
|
||||
| p0s0l |
|
|||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Попробуй писать не record, а packed record...
ЗЫ: позже, посмотрев еще раз вопрос, понял, что дело не в выравнивании... Тут и так всё выравнено... Это сообщение отредактировал(а) p0s0l - 29.11.2004, 16:37 -------------------- С уважением, г-н Посол. |
|||
|
||||
| _hunter |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 8564 Регистрация: 24.6.2003 Где: Europe::Ukraine:: Kiev Репутация: 15 Всего: 98 |
ну и показал бы чем оно заполняется ( желательно в bin ) и чем должно -------------------- Tempora mutantur, et nos mutamur in illis... |
|||
|
||||
| dm9 |
|
|||
![]() Дмитрий Копытин ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 3876 Регистрация: 22.7.2002 Где: Москва Репутация: 6 Всего: 137 |
Извини, что немного не в тему, но, кажется, к сишному типу int будет ближе smallint, а не word
|
|||
|
||||
| _hunter |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 8564 Регистрация: 24.6.2003 Где: Europe::Ukraine:: Kiev Репутация: 15 Всего: 98 |
с какой это радости ( или под какую ось/компилятор )?
из справки:
-------------------- Tempora mutantur, et nos mutamur in illis... |
|||
|
||||
| dm9 |
|
|||
![]() Дмитрий Копытин ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 3876 Регистрация: 22.7.2002 Где: Москва Репутация: 6 Всего: 137 |
_hunter, конечно, могу что-то не понимать, но сказано было, что сишный int занимает 2 байта:
Я уточнил, что если это так, и int этот не unsigned, то правильнее использовать SmallInt, а не Word. А под какой компилятор? Ну, под Borland C++ 3.1, например... Под ДОС. 32-разрядные версии уже будут использовать 4-байтный int (опять-таки, насколько я знаю), там надо брать Integer или LongWord в случае беззнакового числа. Это сообщение отредактировал(а) dm9 - 30.11.2004, 14:55 |
|||
|
||||
| unreg |
|
|||
|
Unregistered |
Я выбрал word потому, что отрицательных значений эти параметры не могут принимать физически. Так же они не могут принимать значения выше верхнего предела SmallInt. Разницы для меня в данном случае нет. Word - писать короче. Да и нет с ними проблемы.
Что возвращается: если поставить Single, то 2,07446823360182E-40 (неправильно). Если array [0..3] of byte, то 50,0126495361328 (правильно). B двоичном сейчас нет возможности показать. |
|||
|
||||
| _hunter |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 8564 Регистрация: 24.6.2003 Где: Europe::Ukraine:: Kiev Репутация: 15 Всего: 98 |
а хоть в hex ( к нему и приводить проще и видно лучше чем так )
-------------------- Tempora mutantur, et nos mutamur in illis... |
|||
|
||||
| unreg |
|
|||
|
Unregistered |
Че-то, вообще, бред какой-то...
Вот структура: TStruct = record time: cardinal; Vmax:word; Smax:word; FR: array [0..3] of byte; Завел еще массив a:array [0..3] of byte; Прочитал структуру и сделал Move(Struct.FR,a,4); массив заполнился следующим: 60 0 72 66. (правильно) Изменил описание FR на Single; Прочитал структуру и сделал Move(Struct.FR,a,4); массив заполнился следующим: 72 66 2 0. (не правильно) Не смотря на мои эксперименты, остальные поля заполнялись верно. А теперь самое интересное: Изменил описание массива а: var a:array [0..5] of byte; В структуре, поле FR описал точнно так же. Прочитал структуру и сделал Move(Struct.FR,a,6); массив заполнился следующим: 60 0 72 66 2 0 (дурдом на выезде) Да, еще забыл сказать, что эта струтктура в файле не единственная, он большой и там много всего. Тем не менее: Читаю по одному смещению. Количество байт строго определено. Что за кака? |
|||
|
||||
| <Spawn> |
|
||||
![]() Око кары:) ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2776 Регистрация: 29.1.2003 Где: Екатеринбург Репутация: 44 Всего: 64 |
Покажи как ты читаешь данные в структуру.
Я толька что проверил вот этот вариант:
И у меня все работает нормально:
Отсюда напрашивается один вывод - ты как то не верно читаешь данные в TStruct.FR -------------------- "Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков. |
||||
|
|||||
| p0s0l |
|
||||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Судя по описанию - всё-таки возможно проблема в выравнивании...
Только непонятно, откуда она берётся - ведь структура уже выравнена. Если бы вместо Cardinal был Word, то да, была бы 100% такая проблема, если в опциях компилятора выставлено выравнивание 4 или 8 байт... Единственное предположение, что ты где-то до описания этой структуры или в модулях, прописанных в Uses сделал описание кардинала таким:
Если делаешь Single - то он выравнивается по границе 4 байт, т.е. до FR вставятся два левых ненужных байта... Но опять же если бы ты переопределил тип Cardinal, то первые три поля структуры заполнились бы не теми данными (ведь time должен быть 4 байта)... Чтобы не гадать, скажи, что выдаёт у тебя SizeOf(TStruct) в случаях, если FR : array[0..3] of byte и FR : Single; Также, всё-таки, на всякий случай (чем черт не шутит ?), напиши так:
Или в опциях компилятора выстави Record Field Alignment в 1, или напиши вначале {$A1} Также вместо массива FR : array [0..3] of byte попробуй написать FR : DWORD или FR : Integer, и cделать Move (как ты уже делал) - что будет в таком случае ? Либо же проблема со чтением, как предположил <Spawn>... -------------------- С уважением, г-н Посол. |
||||
|
|||||
| unreg |
|
|||
|
Unregistered |
Извиняюсь, что долго не отвечал. Возможности не было.
PoSol, действительно, размер структуры меняется. Полностью моя структура выглядит так:
В случае с Single: SizeOf(TMainStruct) = 40, в случае с array [0..3] of byte: SizeOf(TMainStruct) = 36. Читаю структуру из файла: var F:TFileStream; //читаю по нулевому смещению, структура находится в начале файла; F.Read(MainStruct,SizeOf(TMainStruct)); Видимо, дело действительно в выравнивании. Где в компиляторе находятся эти опции? И, если возможно, по-подробнее про выравнивание расскажите. Если я правильно понял, то под Single выделяется 8 байт как на Real, но значение имеют только 4? |
|||
|
||||
| <Spawn> |
|
|||
![]() Око кары:) ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2776 Регистрация: 29.1.2003 Где: Екатеринбург Репутация: 44 Всего: 64 |
Сделай packed record, как тебе уже сказал p0s0l, и будет у тебя структура занимать 36 байт.
Это сообщение отредактировал(а) <Spawn> - 6.12.2004, 05:46 -------------------- "Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков. |
|||
|
||||
![]()
|
| Правила форума "Delphi: Общие вопросы" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |