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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 17.12.2009, 01:17   #1
Hitcher666
Новичок
Джуниор
 
Регистрация: 17.12.2009
Сообщений: 4
Сообщение Подсобите откорректировать программу-архиватор

Здравствуйте.
У меня имеется простенький архиватор, работающий по принципу замены одинаковых подряд символов в .txt файлах и создающий архив .rec . Проблема в том, что упаковывает он толком текстовые файлы, а при распаковке почему-то последний символ повторяется три раза (это если в исходном текстовом был 1), когда в исходном больше 1, там 5 символом, в распакованном становится 25. В результате, при распаковке получается файл текстовый больше, чем исходный txt-шный.
Не могу понять почему так происходит и как это поправить. Прошу, помогите подправить код, а то сроки поджимают к сдаче работы.
Hitcher666 вне форума Ответить с цитированием
Старый 17.12.2009, 01:19   #2
Hitcher666
Новичок
Джуниор
 
Регистрация: 17.12.2009
Сообщений: 4
По умолчанию

Код программы:
Код:
P8086         ;выбор процессора
MODEL SMALL   ;выбор модели
DOSHEAP = 0   ;указывает, будет ли использоваться куча ДОС, или
              ;внутренняя куча; 1- индицирует кучу ДОС; 0-внутреннюю
org 100h;
STACK 200h    ;резервирует пространство стека, необходимое приложению

DATASEG
   Text1 db 'Нажмите Enter и введите имя файла в формате: <имя>.<расширение> или нажмите Esc для выхода.$'
   Text2 db 'Вас приветствует архиватор текстовых файлов!',13,10,' $'
   Text3 db 'Файл в директории запуска имеющий расширение *.rec, будет распакован в файл с $'
   Text4 db 'расширением *.txt; с расширенем *.txt упакован в архив *.rec.',13,10,' $'
   ErrOpenMsg db 'Не удается открыть файл. Возможно неверно введено имя. $';
   ErrCreateMsg db 'Конечный файл уже существует. Перезаписать? [Y/N].$';
   Ent db 13,10,'$'                                     ;перевод строки
   Counter dw 0;
   Repeat  db 0;    счетчик повторов
   LastByte db 0;   последний считанный байт
   CurrentByte db 0;
   SourceLength dw 0;             длина исходного файла
   SourceFile dw 0,0;             описатель исходного файла
   TargetFile dw 0,0;             описатель создаваемого файла
   ;имя исходного файла
   SourcePath db  'source.txt                            '
   ;имя создаваемого файла
   TargetPath db  'target.rec                            '
   Max db 255
   Len db 0
   Bufer db 0;                    буфер чтения



CODESEG
   ;начало исполняемого кода
   STARTUPCODE
   ;EXE программа получает всю доступную ей память

IF DOSHEAP
   ;Освобождается вся память за исключением используемой в текущее время
   ;Конец стека является концом части программы, неразмещенной в куче
   MOV BX,SP
   ADD BX,15    ;выравнивает SP по границе параграфа
   SHR BX,4
   MOV AX,SS    ;вычисляется размер программы, используя ES PSP адрес
   ADD BX,AX
   MOV AX,ES
   SUB BX,AX
   MOV AH,4AH   ;изменяется размер блока памяти вместе с PSP
   INT 21H      ;адресация в ES
ENDIF

;исполняемый код пользователя.

   call StartProgram
   call OpenSource;
   call GetSourceLength;
   call Handler;
   mov BX,SourceFile; закрыть исходный файл
   call Close;
   mov BX,TargetFile; закрыть созданный файл
   call Close;
Exit:
   ;Выход в ДОС по завершению
   MOV AH,4CH
   INT 21H

StartProgram Proc
    mov AH,0; установка режима монитора
    mov AL,3; текстовый 80*25
    int 10h;
    ;вывод общей информации
    lea DX,Text2;
    call WriteLN
    lea DX,Text3;
    call WriteLN
    lea DX,Text4;
    call WriteLN
    ret
StartProgram Endp

OpenSource Proc
    jmp Inp
 ErrOpen:
    lea DX,ErrOpenMsg
    call Writeln
 Inp:
    ;вывод подсказки
    lea DX,Text1;
    call WriteLN 
;ввод строки с именем файла
    call ReadLN
    lea DX,Bufer;
    mov AL,0;     открыть для чтения
    mov AH,3Dh;   функция открытия файла
    int 21h;      открываем
    jc ErrOpen;
    mov SourceFile,AX; запоминаем описатель исходного файла
    ret
OpenSource Endp

Handler Proc
   ;определяет расширение обрабатываемого файла
   ;и запускает нужную подпрограмму обработки
   mov BH,0
   mov BL,Len
   sub BX,3
   ; анализируем расширение
Sim1:
   cmp [Bufer+BX],'r';
   jz Sim2
   cmp [Bufer+BX],'R';
   jnz Select2          ;расширение точно не 'rec' значит пакуем файл
Sim2:
   cmp [Bufer+BX+1],'e';
   jz Sim3
   cmp [Bufer+BX+1],'E';
   jnz Select2          ;расширение точно не 'rec' значит пакуем файл
Sim3:
   cmp [Bufer+BX+2],'c';
   jz Select1
   cmp [Bufer+BX+2],'C';
   jnz Select2          ;расширение точно не 'rec' значит пакуем файл

Select1:
   call UnPack    ;запускаем распаковщик
   jmp EndSelect

Select2:
   call Pack      ;запускаем упаковщик

EndSelect:
   ret
Handler Endp

CreateTarget Proc
   ;создать новый файл и открыть его для записи
   lea DX, TargetPath
   mov CX,0;    атрибут файла
   mov AL,1;    открыть для записи
   mov AH,5Bh; функция создания файла,если файл существовал, то
             ; его содержимое не уничтожается, а возводится флаг С
   int 21h   ; создаем файл
   jnc CreateOk ;файл успешно создан существует

   ;файл существует. запрос подтверждения перезаписи
   lea DX,ErrCreateMsg;
   call WriteLN;
   ;анализ клавиатуры
Hitcher666 вне форума Ответить с цитированием
Старый 17.12.2009, 01:20   #3
Hitcher666
Новичок
Джуниор
 
Регистрация: 17.12.2009
Сообщений: 4
По умолчанию

продолжение
Код:
KeyWait:
   mov AH,7; ввод символа с клавиатуры без отображения с ожиданием ввода
   int 21h;
   ;код в AL

   ;подтверждение перезаписи
   cmp AL,121; 'y'
   jz  Owerwrite
   cmp AL,89;  'Y'
   jz  Owerwrite

   ;отрицание перезаписи
   cmp AL,78; 'N'
   jz  ProgramStop;
   cmp AL,110; 'n'
   jz  ProgramStop;

   jmp KeyWait;

ProgramStop:
   ;Выход в ДОС по завершению
   MOV AH,4CH
   INT 21H

Owerwrite:
   ;перезаписать файл и открыть его для записи
   lea DX, TargetPath
   mov CX,0;    атрибут файла
   mov AL,1;    открыть для записи
   mov AH,3Ch; функция создания файла,если файл существовал, то он создается заново
   int 21h;     создаем файл

CreateOk:
   mov TargetFile,AX; запоминаем описатель создаваемого файла

   ret
CreateTarget ENDP

GetSourceLength Proc
  ;определение длины исходного файла
  mov BX,SourceFile;
  mov CX,0;
  mov DX,0;
  mov AH,42h; функция установки указателя в файле
  mov AL,2;   установка в позицию "конец файла + CX:DX"
  int 21h;
  mov SourceLength,AX;
  mov CX,0;
  mov DX,0;
  mov AH,42h; функция установки указателя в файле
  mov AL,0;   установка в позицию "начало файла + CX:DX"
  int 21h;
  ret
GetSourceLength Endp

Pack Proc
   ;формируем имя архива
   mov CH,0
   mov CL,len
   sub CL,4
   mov BX,CX
   mov [TargetPath+BX],'.';
   mov [TargetPath+BX+1],'r';
   mov [TargetPath+BX+2],'e';
   mov [TargetPath+BX+3],'c';
   mov [TargetPath+BX+4],0;
next:
   mov BX,CX
   mov AL,[Bufer+BX-1];
   mov [TargetPath+BX-1],AL;
   loop next;

   ;создаем файл и открывем его
   call CreateTarget;

  ;помещаем в счетчик длину исходного файла
  mov AX,SourceLength;
  mov Counter,AX;


  читаем первый байт
  lea DX,LastByte;
  mov BX,SourceFile;
  mov CX,1;   число байт
  mov AH,3Fh; функция чтения из файла
  int 21h;
  mov Repeat,0; повторов пока нет

NextByte:
  ;читаем байт из исходного файла
  lea DX,CurrentByte;
  mov BX,SourceFile;
  mov CX,1;   число байт
  mov AH,3Fh; функция чтения из файла
  int 21h;
  mov AL,CurrentByte
  cmp LastByte,AL;
  jnz Wri           ; текущий байт отличен от предыдущего
  inc Repeat        ; текущий байт совпадает с предыдущим
  cmp Repeat,255d;
  jz  Wri;
  jmp Continue


Wri:
  cmp Repeat,0;
  jz Wri2         ;предыдущий символ встречался 1 раз

  mov BX,TargetFile
  mov [Bufer],27d ;отметка что символ встречается более 1 раза
  lea DX,Bufer
  mov CX,1;
  mov AH,40h; функция записи в файл
  int 21h;
  lea DX,Repeat
  mov CX,1;
  mov AH,40h; функция записи в файл
  int 21h;


Wri2:

  ;записываем предыдущий байт в создаваемый файл
  mov BX,TargetFile
  lea DX,LastByte;
  mov CX,1;
  mov AH,40h; функция записи в файл
  int 21h;
  ;запоминаем текущий байт
  mov AL,CurrentByte;
  mov LastByte,AL;
  mov Repeat,0;
Continue:
  dec Counter
  jnz NextByte

  ;запись последнего байта
  mov BX,TargetFile
  lea DX,CurrentByte;
  mov CX,1;
  mov AH,40h; функция записи в файл
  int 21h;

  ret
Pack Endp

UnPack Proc
   ;формируем имя распакованого файла
   mov CH,0
   mov CL,Len
   sub CL,4
   mov BX,CX
   mov [TargetPath+BX],'.';
   mov [TargetPath+BX+1],'t';
   mov [TargetPath+BX+2],'x';
   mov [TargetPath+BX+3],'t';
   mov [TargetPath+BX+4],0;
next2:
   mov BX,CX
   mov AL,[Bufer+BX-1];
   mov [TargetPath+BX-1],AL;
   loop next2;

   ;создаем файл и открывем его
   call CreateTarget;

  ;помещаем в счетчик длину исходного файла
  mov AX,SourceLength;
  mov Counter,AX;

NextByte2:
  ;читаем байт из исходного файла
  lea DX,CurrentByte;
  mov BX,SourceFile;
  mov CX,1;   число байт
  mov AH,3Fh; функция чтения из файла
  int 21h;

  cmp CurrentByte,27d;  проверка метки повтора
  jnz One           ;  нет метки повтора
  ;есть метка повтора. читаем следующий байт - число повторов
  lea DX,Repeat;
  mov BX,SourceFile;
  mov CX,1;   число байт
  mov AH,3Fh; функция чтения из файла
  int 21h;
  inc Repeat;

  ;читаем повторяющийся байт из исходного файла
  lea DX,CurrentByte;
  mov BX,SourceFile;
  mov CX,1;   число байт
  mov AH,3Fh; функция чтения из файла
  int 21h;

  jmp Wri3;
One:
  mov Repeat,1; повторить один раз

Wri3:
  ;записываем в создаваемый файл
  lea DX,CurrentByte;
  mov BX,TargetFile
  mov CX,1;
  mov AH,40h; функция записи в файл
  int 21h;
  dec Repeat;
  jnz Wri3;
  dec Counter
  jnz NextByte2

  ret
UnPack Endp

WriteLN Proc
  ;адрес выводимой строки в DX
  mov AH,9; функция вывода
  int 21h;
  ;переход на следующую строку
  lea DX,Ent;
  mov AH,09h; функция вывода
  int 21h;
  ret
WriteLN Endp
Hitcher666 вне форума Ответить с цитированием
Старый 17.12.2009, 01:22   #4
Hitcher666
Новичок
Джуниор
 
Регистрация: 17.12.2009
Сообщений: 4
Сообщение

окончание
Код:
ReadLN Proc ;  ввод имени файла
  ; ввод имени файла
  lea DX,Max; указываем на буфер ввода
  mov AH,0Ah; буферизованный ввод с клавиатуры
  int 21h;

  ;переход на следующую строку
  lea DX,Ent;
  mov AH,09h; функция вывода
  int 21h;

  ;дополняем путь символом 0
  mov BL,len;
  mov BH,0
  mov [BX+Bufer],0;

  ret
ReadLN Endp;

Close Proc
   ;описатель файла в BX
   ;закрыть файл
   mov AH,3Eh; функция закрытия файла
   int 21h;    ;выполняем закрытие
   ret
Close Endp

END
Буду очень признателен за помощь. Как мне думается ошибка где-то в Pack/Unpack процедурах, но я её не вижу, в этом и проблема.
Hitcher666 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Архиватор Хаффмана zetrix Софт 17 15.03.2014 13:45
Архиватор DMITRIG Общие вопросы C/C++ 2 03.05.2008 14:36
Архиватор Mcc_1 Фриланс 4 18.12.2007 18:19
Архиватор методом Running radist Помощь студентам 1 15.05.2007 17:46
Архиватор. Elektronbrain Фриланс 51 10.02.2007 10:09