Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.04.2012, 18:12   #1
Arrow_S
 
Регистрация: 28.03.2012
Сообщений: 4
По умолчанию Delphi. Динамический массив при работе с нетипизированными файлами

Здравствуйте, столкнулся с проблемой при работе с двоичным файлом. В файле блоки данных разного размера, поэтому приходится использовать динамический массив. У каждого блока есть заголовок 27 байт, в котором зашита длина всего блока. В зависимости от данных блоки записываются в разные файлы.
При использовании динамического массива "PDP: Array of Char", программа зависает на второй итерации. При копировании части строки PZPBIN в Lpak. Lpak - строка с длинной блока данных.

Туплю второй день, не могу догнать в чём проблема. Кто может подскажите, заранее спасибо.

Код:
procedure TForm2.BitBtn1Click(Sender: TObject);
var
TM, Vospr: file;
I, Lp, S: integer;
VosprF, VosprF1:String;
Zagolovok: Array [0..255] of Char;
PZP:Array [0..26] of Char;
N: Array [0..26] of Integer;
PDP: Array of Char;
PZPHEX, PZPBIN, IDpak, Npak, Lpak: String;

begin
  if OpenDialog1.Execute then
  Begin

// открытие ТМ файла и создание файла Vospr
 
   VosprF:= OpenDialog1.FileName;
   VosprF1:=VosprF;
   S:=Length(OpenDialog1.FileName)-11;
   Insert('VOSPR', VosprF1, S);

// Связь файлов с файловыми переменными

   AssignFile(TM, OpenDialog1.FileName);
   AssignFile(Vospr,VosprF1);

// Открытие файлов

   {$I-}
   Reset(TM,1);
   Rewrite(Vospr,1);
   {$I+}

// Проверка операции открытия файлов

   I:=IOResult; if I<>0  then Exit;

// Считывание и запись заголовка ТМ файла

   FileMode :=fmOpenReadWrite;
   BlockRead(TM, Zagolovok, 256);
   BlockWrite(Vospr, Zagolovok, 256);


// Основной блок

   while not Eof(TM) do
    begin

//Считывание заголовка блока

      blockread(TM,PZP,27);

// Расшифровка заголовка блока

      for I := 0 to 26 do
      Begin
      	n[i]:=Ord(PZP[i]);
   	PZPHEX:=PZPHEX+IntToHex(n[i],2);
      End;

      PZPBIN:= HexToBin(PZPHEX);

// Определение длинны блока

// Зависает в этом месте     
     Lpak:=Copy(PZPBIN,201,16);
     Lpak:=BinToHex(Lpak);
     Lpak:=IntToStr(HexToInt(Lpak)+1);
     Lp:= StrToInt(Lpak);

// Запись заголовка в файл Vospr

     blockwrite(Vospr, PZP, 27);

// Считывание и запись данных блока

    // Правильно ли здесь идет передача данных?
     
     SetLength(PDP, Lp);
     blockread(TM,PDP,Lp);
     blockwrite(Vospr, PDP, Lp);


   PZPHEX:='';
   PZPBIN:='';

  end;

   CloseFile(TM);
   CloseFile(Vospr);

   label1.Caption:='Файл ТМ: '+Copy(OpenDialog1.FileName, S, 12)+' - обработан!';
   label1.Visible:=True;
  End;

end;
Arrow_S вне форума Ответить с цитированием
Старый 03.04.2012, 18:27   #2
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Было бы неплохо поСЧупать ваш ЕНтот файл TM. Если он не велик, то залейте во вложения. Иначе трассируйте и просматривайте состояния переменных. Возможно вы пытаетесь считать огромный блок данных, возможен выход за пределы файла при считывании, или ещё что-нибудь.
Если помог, проси поставить минус. Будь оригинален!

Последний раз редактировалось Rin; 03.04.2012 в 18:32.
Rin вне форума Ответить с цитированием
Старый 03.04.2012, 18:35   #3
Arrow_S
 
Регистрация: 28.03.2012
Сообщений: 4
По умолчанию

Файл великоват, а при трассировке переменная Lp =10, первые несколько блоков по 37 байт, 27 заголовок и 10 данные. Проблема в том, что я как то неправильно работаю с массивом(, или в передаче данных. Со статичным массивом на 10 элементов (например), из файла в файл перегоняется на раз, но данные не все по 10 байт, а с динамическим беда.
Arrow_S вне форума Ответить с цитированием
Старый 03.04.2012, 19:30   #4
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,429
По умолчанию

Есть ли гарантии, что длина PZPBIN всегда 216 символов?
Вставьте showmessage с длиной перед копированием.
И вообще, зачем его "вытаскивать" из строки?
Это значение хранится в n[26] (имхо).
Я вообще не понял, зачем создавать столько промежуточных строк, чьи значения больше никак не используются, но вам, конечно, виднее, какая информация должна быть обработана.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 03.04.2012 в 19:33.
BDA вне форума Ответить с цитированием
Старый 03.04.2012, 19:35   #5
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Сделайте проверку что ли
Код:
if length(PZPBIN)>=216 then Lpak:=Copy(PZPBIN,201,16);
Если помог, проси поставить минус. Будь оригинален!

Последний раз редактировалось Rin; 03.04.2012 в 19:47.
Rin вне форума Ответить с цитированием
Старый 03.04.2012, 19:38   #6
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,429
По умолчанию

Rin, длина PZPBIN меньше или равна 216
И вот если меньше, то лучше так не копировать)
Тогда уж Lpak:=Copy(PZPBIN,length(PZPBIN)-15,16);
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 03.04.2012, 19:43   #7
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

BDA, условие я предлагаю, чтобы при трассировке можно было посмотреть, длина массива >= 216, или все таки нет.
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 03.04.2012, 19:45   #8
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,429
По умолчанию

Тогда исправьте в своем сообщении знак ">" на ">=", а то ввели меня в заблуждение
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 03.04.2012, 20:09   #9
Arrow_S
 
Регистрация: 28.03.2012
Сообщений: 4
По умолчанию

Длина PZPBIN всегда равна 216, последние 2 байта = длина инф. части. Да и с пеобразованиями проблем при трассировке нет. Проблема, на мой взгляд, с дин. массивом и передачей значений в связке этих операторов.

Код:
 Lpak:=Copy(PZPBIN,201,16);
     Lpak:=BinToHex(Lpak);
     Lpak:=IntToStr(HexToInt(Lpak)+1);
     Lp:= StrToInt(Lpak);


     SetLength(PDP, Lp);
     blockread(TM,PDP,Lp);
     blockwrite(Vospr, PDP, Lp);
Такое ощущение, что что то "держит" данные Lpak и не даёт их изменить.
Команды, типа:
SetLength(PDP, 0);
Finalize(PDP);
PDP:=nil;
Lpak:='';
в концовке цикла сразу приводят к зависанию и выдают ошибку доступа к каким-то адресам памяти.

Последний раз редактировалось Arrow_S; 03.04.2012 в 20:18.
Arrow_S вне форума Ответить с цитированием
Старый 03.04.2012, 21:14   #10
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,542
По умолчанию

Код:
   // Правильно ли здесь идет передача данных?
     
     SetLength(PDP, Lp);
     blockread(TM,PDP[0]@,Lp);
     blockwrite(Vospr, PDP[0]@, Lp);
для динамических массивов надо указывать алрес первого (нулевого) элемента.
но модет быть надо так @PDP[0]
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 03.04.2012 в 21:17.
evg_m вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема при работе с файлами stck Паскаль, Turbo Pascal, PascalABC.NET 1 21.12.2011 11:28
Работа с нетипизированными файлами JustKurt Общие вопросы Delphi 4 18.07.2009 10:46
проблема при работе с несколькими исходными файлами Grind Помощь студентам 2 19.02.2008 19:37
ошибка 105 (при работе с типизированными файлами) sdp Общие вопросы Delphi 8 11.07.2007 11:12