Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 16.01.2011, 16:28
AleXXXSC AleXXXSC вне форума
Прохожий
 
Регистрация: 16.01.2011
Сообщения: 2
Репутация: 10
По умолчанию TMemoryStream, буферы, строки....

Дано: D7, Win XP SP3,бинарный файл.
В файле по определенным и заранее известным смещениям хранятся строки. Под строку в файле отведено 32 байта, причем если строка короче 32 символов - строка дополнена #00 до нужной длины. Следом идет уже другая информация с любым hex кодом.

Необходимо получить эту строку для дальнейшей работы с ней. Сейчас выполнено так.
Пример бинарного файла(начало):
Код:
04h 01h 00h 00h НУЖНАЯ СТРОКА ИЗ 32 БАЙТ 00h 00h 00h 00h 00h 00h 00h 00h XXh XXh.....

Программный код:
Код:
.........
Var
MS: TMemoryStream;
binRowsCount: integer;
TC : record
  Name      : String[33];
  ......
end;
begin
MS:=TMemoryStream.Create; 
MS.LoadFromFile(Path);

MS.Read(binRowsCount,4); //чтение 4 байт, указатель смещается на 4;
TC.Name:=''; // хочу обнулить т.к. там абракадабра по умолчанию 
MS.ReadBuffer(TC.Name,32); //собственно чтение этой 32-байтной строки
TC.Name[32]:= #00; //сделать нуль-терминированную строку т.к. мало ли что там в конце осталось
........
end
.

В релультате имеем:
TC.Name=УЖНАЯ СТРОКА ИЗ 32 БАЙТ||||||||| ,
где 1-й символ (Н) отсутствует, а строка дополнена непечатными символами (|).

Подскажите, пожалуйста, что не правлильно я делаю.
Ответить с цитированием
  #2  
Старый 16.01.2011, 20:14
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от AleXXXSC
Подскажите, пожалуйста, что не правлильно я делаю.

Код:
var
  MS : TMemoryStream;
  pS : PChar;
  S : String;
  Stub : DWORD;
begin
  ...
  MS.ReadBuffer(Stub,4);

  GetMem(pS,33);
  MS.readBuffer(pS^,32);
  S := StrPas(pS);
  FreeMem(pS,33);
  ...

как-то так. С крышкой (^) надо проверить - нужна ли она...
Ответить с цитированием
  #3  
Старый 16.01.2011, 21:01
AleXXXSC AleXXXSC вне форума
Прохожий
 
Регистрация: 16.01.2011
Сообщения: 2
Репутация: 10
По умолчанию

Пробедил
Вместо
Код:
TC : record
  Name      : String[33];
  .....
Написал

Код:
TC : record
  Name    : array[0..32] of char;
  .....

Ассемблерный дебаг показал что хитрые строки в дельфи хранят еще и длину строки перед началом 1-го символа. Поскольку Name была объявлена как 33 символа, то для длины строки, видимо, хватило 1 байта. Похоже что 1-й символ поэтому и пропал, что начал обозначать длину строки. Это же и подтвердила операция
Код:
 S:=TC.Name+'' ;
когда при создании строки S было выделено количествро байтов равным коду 1-го символа. Видимо против всяких Stack overflow сдалали

P.S. Тему можно закрывать, за ответ спасибо.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 21:52.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025