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

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

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 30.01.2022, 05:37   #181
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
Отдельно на кнопки три сделал. всё отлично. а с чекбоксом ни как.
Ура ! получилось с чексбоксом , сделал всё работает корректно.

Код:
 var
Stream: TMemoryStream;
a: array [0..64] of Byte;
b: array [0..80] of Byte;
C: array [0..80] of Byte;
p: ^Byte;
i:integer;
begin
Label1.Caption :=' ';
dlgOpen.Filter:= 'Bin File (*.Bin)|*.Bin';
if dlgOpen.execute() then

begin
Stream := TMemoryStream.Create;
Stream.LoadFromFile(dlgOpen.FileName);
if Stream.Size > 176 then
ShowMessage('Недопустимый размер файла!')
else
begin
if Combobox1.ItemIndex= 0 then
begin

Label1.Caption := IntToStr(Stream.Size)+ ' '+' '+ 'Byte ';
Stream.Position:=$10;
Stream.Read(a,64);

Stream.Position:=$50;
Stream.Clear;
Stream.Position:=$10;
Stream.write(a,64);

begin
p := Stream.Memory;
inc(p, $0);
for i := 1 to 16 do
begin
p^ := $FF;
inc(p);
end;
dlgsave.Filter:= 'Bin File (*.Bin)|*.Bin';
dlgsave.FileName := dlgopen.FileName;
if not dlgSave.Execute then
exit;
Stream.SaveToFile(dlgSave.FileName +'_ '+'Copy'+'_'+'.bin');
Showmessage(' файл    сделан  !  ');
exit;
end;
end
else


 if Combobox1.ItemIndex=1 then
begin

Label1.Caption := IntToStr(Stream.Size)+ ' '+' '+ 'Byte ';
Stream.Position:=$20;
Stream.Read(b,80);

Stream.Position:=$0;
Stream.Clear;
Stream.Position:=$20;
Stream.write(b,80);
begin
p := Stream.Memory;
inc(p, $0);
for i := 1 to 32 do
begin
p^ := $FF;
inc(p);
end;
dlgsave.Filter:= 'Bin File (*.Bin)|*.Bin';
dlgsave.FileName := dlgopen.FileName;
if not dlgSave.Execute then
exit;
Stream.SaveToFile(dlgSave.FileName +'_ '+'Copy'+'_'+'.bin');
Showmessage( '  файл   сделан  !  ');
exit;
end;
end
else


if Combobox1.ItemIndex=2 then

begin
Label1.Caption := IntToStr(Stream.Size)+ ' '+' '+ 'Byte ';
Stream.Position:=$50;
Stream.Read(C,80);

Stream.Position:=$0;
Stream.Clear;
Stream.Position:=$50;
Stream.write(C,80);
begin
p := Stream.Memory;
inc(p, $0);
for i := 1 to 80 do
begin
p^ := $FF;
inc(p);
end;
dlgsave.Filter:= 'Bin File (*.Bin)|*.Bin';
dlgsave.FileName := dlgopen.FileName;
if not dlgSave.Execute then
exit;
Stream.SaveToFile(dlgSave.FileName +'_ '+'Copy'+'_'+'.bin');
Showmessage( ' файл   сделан  !  ');
end ;
end ;
end ;
Stream.Free;
end ;
end;
Но всё, ровно компонент не удобен, всё через else делать надо а , если 10 вариантов, да ещё с циклами? В общем не удобный в коде компонент.

Ну вот с этим разобрался, но ведь надо главное, в цикле всё это перевести в s19 .
И тут сразу трудность.
1) мы работали с s19 с TFileStream; , а в проге получился только вариант с TMemoryStream;
Эначит всё надо переделывать в s19? 2) Всё это в комбобоксе проделать, к имеющемуся коду. прибавить ещё перевод в s19 и сохранение.

В общем жду помощи, сам не осилю.
Вложения
Тип файла: rar Cut_File-.rar (172.3 Кб, 1 просмотров)
Тип файла: rar Тест- новый.rar (218 байт, 1 просмотров)
sergey.serg-72 вне форума Ответить с цитированием
Старый 30.01.2022, 09:59   #182
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
всё через else делать надо
Во-первых, есть case. Во-вторых, одинаковый код не надо дублировать. Если говорить именно о "вырезалке" куска бина, то:
Код:
procedure TForm1.btn1Click(Sender: TObject);
var
  Stream: TMemoryStream;
  p: ^Byte;
  i, start_pos, end_pos: integer;
begin
  case Combobox1.ItemIndex of
    0:
      begin
        start_pos := $10;
        end_pos := $50;
      end;
    1:
      begin
        start_pos := $20;
        end_pos := $70;
      end;
    2:
      begin
        start_pos := $50;
        end_pos := $A0;
      end;
  else
    ShowMessage('Не выбран диапазон!');
    exit;
  end;

  Label1.Caption := ' ';
  dlgOpen.Filter := 'Bin File (*.Bin)|*.Bin';
  if not dlgOpen.Execute then
    exit;

  Stream := TMemoryStream.Create;
  Stream.LoadFromFile(dlgOpen.FileName);
  if Stream.Size <> 176 then
  begin
    ShowMessage('Недопустимый размер файла!');
    Stream.Free;
    exit;
  end;

  Label1.Caption := IntToStr(Stream.Size) + ' ' + 'Bytes';
  Stream.Size := end_pos;
  p := Stream.Memory;
  for i := 0 to start_pos - 1 do
  begin
    p^ := $FF;
    inc(p);
  end;

  dlgsave.Filter := 'Bin File (*.Bin)|*.Bin';
  dlgsave.FileName := dlgopen.FileName;
  if not dlgSave.Execute then
  begin
    Stream.Free;
    exit;
  end;

  Stream.SaveToFile(dlgSave.FileName + '_Copy_.bin');
  Showmessage('Файл сделан!');
  Stream.Free;
end;
Уже раньше обсуждали, что так проверять размер нельзя (так как файл сразу должен загрузиться в память и может оказаться большим). Возможно можно без цикла записать FF. А если нужно все равно этот кусок бина перегонять в S19, то и менять надо было текущий конвертер bin->srec.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 30.01.2022, 22:01   #183
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Во-первых, есть case. Во-вторых, одинаковый код не надо дублировать. Если говорить именно о "вырезалке" куска бина, то:
Блин , ну что тут сказать? Это высший пилотаж у Вас !!! Я так давно не использовал Case , что забыл про него напрочь.... Одинаковый больше не буду.
А я всю ночь сидел , с комбобоксом отрабатывал до 10 позиций дошёл. Можно и без else и без Case, но код длинноватый будет. Но хоть чексбокс наконец то отработал...
Я его избегал , если честно , из списка старался PopuMenu использовать , тоже выпадающий список, но можно как на одной кнопки использовать.
Препод догадался о слабом месте и в него, ударил....
Да в том то и дело что не просто вырезать , а вырезанный в цикле сохранить в S19.
sergey.serg-72 вне форума Ответить с цитированием
Старый 30.01.2022, 22:14   #184
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Уже раньше обсуждали, что так проверять размер нельзя (так как файл сразу должен загрузиться в память и может оказаться большим). Возможно можно без цикла записать FF. А если нужно все равно этот кусок бина перегонять в S19, то и менять надо было текущий конвертер bin->srec.
Да, Вы правы меня и препод нагрел уже не раз, дурацкая привычка на автомате, а надо обязательно Stream.Free; exit; использовать. чтоб и поток закрыть и выйти из цикла. если ошибочный размер файла. Исправлюсь, обещаю !

Можно и без цикла FF, думаю в данном случаи что так и нужно .
( А если нужно все равно этот кусок бина перегонять в S19, то и менять надо было текущий конвертер bin->srec.) В том то и проблема что кусок надо перегонять в S19, а это значит, что и цикл вообще не нужен из FF. Надо как то вырезанный кусок сразу с адреса скажем 10 записывать в S19 и.т.д А зачем менять сам конвертер ? Тут ситуация другая, надо как то из потока перехватывать вырезанный кусок и сохранять в S19 соответственно адресу. одному из трёх. Я с начало думал сразу справлюсь. а потом понял. что не по зубам пока. Такого ещё. делать не приходилось. Препод подловил и тут.

Цитата:
Сообщение от BDA Посмотреть сообщение
А если нужно все равно этот кусок бина перегонять в S19, то и менять надо было текущий конвертер bin->srec.
Да, похоже тоже не годится, как в одно объединить, ( к одному знаменателю ) и старт и конец, чтоб кусок единым был ? Может S19 отдельной процедурой сделать,а потом перехватывать вырезанный кусок?

думаю что работать надо с массивом . чтоб потом передать процедуре s19 массив и с адреса скажем :fbin.Position:=$10; или с fbin.Position:=$50 и.т.д начинать записывать в s19. По другому, думаю не получится .

Цитата:
Сообщение от BDA Посмотреть сообщение
А если нужно все равно этот кусок бина перегонять в S19, то и менять надо было текущий конвертер bin->srec.
Я понял что Вы имели ввиду, изменить сам конвертер bin- s19 ,я правильно понял?

да, но в задании этот комбобокс должен быть и без него ни как, а в старом всё от кнопки. Вот в чём вопрос.

Последний раз редактировалось BDA; 01.02.2022 в 01:55.
sergey.serg-72 вне форума Ответить с цитированием
Старый 31.01.2022, 05:22   #185
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
да, но в задании этот комбобокс должен быть и без него ни как, а в старом всё от кнопки. Вот в чём вопрос.
Ура ! получилось что и требовалось по заданию, плюс ещё один накинул.
И всё благодаря Вам BDA !. В правильном направление дали пинка.
Вроде всё, компилятор не выписал ни предупреждений, ни советов.
Выношу на суд ваш .
Код:
 const
BYTES_IN_LINE = 16;
sLineEnd = #13#10;
var
fbin, ftxt: TFileStream;
s, data_s: string;
b: TBytes;
 addr: Int64;
i, count, read_count,start_pos, end_pos: integer;
 sum: byte;
begin
case Combobox1.ItemIndex of
0:
begin
start_pos := $10;
end_pos := $50;
end;
1:
begin
start_pos := $20;
end_pos := $70;
end;
2:
begin
start_pos := $50;
end_pos := $A0;
end;
3:
begin
start_pos := $70;
end_pos := $90;
end;
else
ShowMessage('Не выбран диапазон!');
exit;
end;
begin
fbin := nil;
ftxt := nil;
try
try
Label1.Caption:=' ';
dlgOpen.Filter := 'Bin (*.Bin)|*.Bin;*.bin|';
if not dlgOpen.Execute then
exit;
fbin := TFileStream.Create(dlgOpen.FileName, fmOpenRead or fmShareDenyWrite);
if fbin.Size <> 176 then
raise Exception.Create('Слишком большой файл, строго до 176 байт !');
addr := fbin.Size;
if addr > Limit16 then
raise Exception.Create('Слишком большой адрес конца файла!');
Label1.Caption := IntToStr(fbin.Size)+ ' '+ '  '+'Байт ';
dlgsave.Filter:= 'S19_File (*.S19)|*.S19';
dlgSave.FileName := ChangeFileExt(dlgOpen.FileName,'.S19');
if not dlgSave.Execute then
exit;
ftxt := TFileStream.Create(dlgSave.FileName, fmCreate or fmShareDenyWrite);
SetLength(b, BYTES_IN_LINE);
s := 'S00600004844521B' + sLineEnd;
ftxt.Write(s[1], Length(s));
fbin.Position:= start_pos;
while fbin.Position < end_pos do
begin
addr:= fbin.Position;
read_count := fbin.Read(b[0], BYTES_IN_LINE);
count := read_count +  3;
sum := count + addr and $FF + (addr shr 8) and $FF;
data_s := '';
for i := 0 to read_count - 1 do
begin
data_s := data_s + IntToHex(b[i], 2);
Inc(sum, b[i]);
end;
sum := $FF - sum;
s := Format('S1%.2x%.4x%s%.2x', [count, addr, data_s, sum])+ sLineEnd;
ftxt.Write(s[1], Length(s));
end;
s :='S9030000FC'+ sLineEnd;
ftxt.Write(s[1], Length(s));
MessageBox(handle,PChar('Файл преобразован и записан в формат  s19'+#13#10), PChar('Сообщение'), 64);
except
on E : Exception do
Application.MessageBox(PAnsiChar(E.Message), 'Converter', MB_Ok + MB_ICONERROR);
end;
finally
fbin.Free;
ftxt.Free;
end;
end;
end;
case вообще вещь классная !
p.s
Сегодня утилиту от Нода прислали прогнал всю папку Борланд и exe -шники, вирусов нет.
Вложения
Тип файла: rar Cut_File_to_S19_.rar (172.1 Кб, 0 просмотров)
Тип файла: rar Тест- новый.rar (218 байт, 0 просмотров)
sergey.serg-72 вне форума Ответить с цитированием
Старый 31.01.2022, 06:19   #186
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
получилось что и требовалось по заданию
Вот видите, можете и сами справиться. Код не запускал, но выглядит правдоподобно. Бегло по коду: сравнение с Limit16 не нужно, так как размер уже определен в 176 байт, а смещение в данном коде не делается. Чтение сделал бы в таком виде:
Код:
read_count := fbin.Read(b[0], min(BYTES_IN_LINE, end_pos - addr));
Это на случай, если размер вырезаемой области не кратен BYTES_IN_LINE.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 31.01.2022, 22:36   #187
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
read_count := fbin.Read(b[0], min(BYTES_IN_LINE, end_pos - addr));
Цитата:
Сообщение от BDA Посмотреть сообщение
Вот видите, можете и сами справиться. Код не запускал, но выглядит правдоподобно. Бегло по коду: сравнение с Limit16 не нужно, так как размер уже определен в 176 байт, а смещение в данном коде не делается. Чтение сделал бы в таком виде:
Да шиш бы я что смог бы , если бы не Ваша неоценимая помощь !!!
Limit16 убрал. согласен он лишний. Код работает ,это факт. Но это только Ваша. целиком заслуга.

Цитата:
Сообщение от BDA Посмотреть сообщение
read_count := fbin.Read(b[0], min(BYTES_IN_LINE, end_pos - addr));
Это на случай, если размер вырезаемой области не кратен BYTES_IN_LINE.
Ругается компилятор , не нравится ему строка и как я понял проблема в min. это что и какая переменная , её предназначение ? что за минимум ?
Изображения
Тип файла: jpg 1.JPG (21.6 Кб, 14 просмотров)

Последний раз редактировалось BDA; 01.02.2022 в 01:55.
sergey.serg-72 вне форума Ответить с цитированием
Старый 01.02.2022, 01:57   #188
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
как я понял проблема в min
Нужно в uses добавить модуль Math. Это функция, возвращающая минимальное из 2 чисел-аргументов.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 01.02.2022, 04:03   #189
sergey.serg-72
Форумчанин
 
Регистрация: 12.03.2019
Сообщений: 376
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Нужно в uses добавить модуль Math. Это функция, возвращающая минимальное из 2 чисел-аргументов.
да, я подумал что может быть модуль.
Как я понимаю то менять надо и здесь :
Код:
 while fbin.Position < end_pos  do
на так :
Код:
 while fbin.Position < fbin.Size  do
?

Тут есть проблема , допустим снимаю ограничение на размер файла, и получается что если адрес выходит за размер файла, то жестко зависает прога. При чём что с одним вариантом, что со вторым. Надо какую то обработку на случай выхода адреса за размер файла.
Что то упустили...
sergey.serg-72 вне форума Ответить с цитированием
Старый 01.02.2022, 06:18   #190
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Цитата:
Сообщение от sergey.serg-72 Посмотреть сообщение
если адрес выходит за размер файла, то жестко зависает прога
Да, такой вариант не рассматривался:
Код:
if fbin.Size + 1 < end_pos then
  raise Exception.Create('Слишком большой адрес конца файла!');
// или
while fbin.Position < min(fbin.Size, end_pos) do
// или
read_count := fbin.Read(b[0], min(BYTES_IN_LINE, end_pos - addr));
if read_count = 0 then
  break;
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Нужно создать "батник", вырезать из "2.txt" первых n строк и вставить их в "1.txt" temphard Помощь студентам 2 03.09.2013 16:03
Удаление первых n-строк из txt-файла Neksion Помощь студентам 2 10.07.2013 18:12
Создать чтение из файла и запись в файл txt на С++ skifre Фриланс 0 01.06.2012 16:16
поиск и выципление строк из txt файла D_e_n_n Помощь студентам 7 04.02.2011 05:39
C# Представление txt файла как массива строк asheb Помощь студентам 7 20.04.2010 12:51