Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛПЗ(8-10).docx
Скачиваний:
7
Добавлен:
17.11.2018
Размер:
60.24 Кб
Скачать

2.4 Результаты работы программы

Тест 1.

Исходный файл task2_in.txt

14,145,70,90,19,14,20,35,90,5,15,190,280,98,28

Полученный файл task2_ou.txt

145,90,20,90,5,15,190

7

555

Тест 2.

Исходный файл task2_in.txt

3,4110212900,3500000000,100000

Полученный файл task2_ou.txt

4110212900,100000

2

4110312900

Тест 3.

Исходный файл task2_in.txt

4,4110212900,3500000000,100000

Полученный файл task2_ou.txt

Ошибка. Недостаточно данных в исходном файле.

Тест 4.

Исходный файл task2_in.txt

2,4110212900000,35

Полученный файл task2_ou.txt

Ошибка. Разрядность исходного числа превышает формат короткого целого.

3. Лабораторная работа №10

3.1. Задание

Даны 2 символьных файла f1 и f2. Файл f1 содержит произвольный текст. Слова в тексте разделены пробелами и знаками препинания. Файл f2 содержит слова, разделённые запятыми. Эти слова образуют пары: каждое первое слово считается заменяемым, каждое второе заменяющим. Найти в файле f1 все заменяемые слова и заменить их на соответствующие заменяющие. Результат поместить в файл g. После преобразования тестовый файл g необходимо сформатировать.

3.2. Блок-схема алгоритма

3.3. Текст программы

.386

data segment use16

buff_tx db 10240 dup (?) ;Текстовый буфер

b_point dw 0 ;Указатель в буфере

F_Len dw ? ;Длина входного файла

exit db 0 ;=1 если найден разделитель

Next_st dw ?

File_i1 db 'task3_1.txt',0 ;Имя входного файла c текстом

Handle1 dw 1 ;Описатель 1-го файла

File_i2 db 'task3_2.txt',0 ;Имя входного файла с ключами

Handle2 dw 1 ;Описатель 2-го файла

File_ou db 'task3_3.txt',0 ;Имя выходного файла с текстом

Handle3 dw 1 ;Описатель 3-го файла

first db 64 dup (?) ;Заменяемое слово

first_l dw 0 ;Длина заменяемого слова

second db 64 dup (?) ;Заменяющее слово

sec_l dw 0 ;Длина заменяющего слова

third_l dw 0 ;Длина обрабатываемого слова

cr db 0ah,0dh

end_f2 db 0

mes1 db 'Ошибка. Невозможно открыть файла "task3_1.txt".',0ah,0dh,'$'

mes2 db 'Ошибка. Невозможно открыть файла "task3_2.txt".',0ah,0dh,'$'

mes3 db 'Ошибка. Размер файла больше 10240 байт.'

mes4 db 'Ошибка. Невозможно создать файл "task3_3.txt".',0ah,0dh,'$'

mes5 db 'Ошибка. Невозможно записать в файл "task3_3.txt".',0ah,0dh,'$'

mes6 db 'Ошибка. Невозможно прочитать из файл "task3_2.txt".',0ah,0dh,'$'

mes7 db 'Ошибка. Количество слов в "task3_2.txt" нечётно.',0ah,0dh,'$'

mes8 db 'Ошибка. Размер файла превышает 10240 байт.',0ah,0dh,'$'

data ends

stack segment use16 stack

db 100 DUP(?)

stack ends

code segment use16

assume cs:code,ds:data,es:data,ss:stack;

main:

mov ax,data

mov ds,ax

mov es,ax

mov ax,stack

mov ss,ax

lea dx,File_i1

mov ah,3Dh

mov al,0

int 21h ; Открытие файла 'task3_1.txt'

jc err1

mov Handle1,ax

mov bx,ax

mov ah,3Fh

mov cx,10240

lea dx,buff_tx

int 21h ; Чтение 10240 байт файла

mov F_len,ax

mov ah,3Eh

mov bx,handle1

int 21h ; Закрытие файла

cmp ax,10240 ;Проверка на слишком большой файл

jz err3

lea dx,File_i2

mov ah,3Dh

mov al,0

int 21h ; Открытие файла 'task3_2.txt'

jc err2

mov Handle2,ax

;---------------------------------------------------------------------------

;Начало обработки файла

rep2:

push ax

mov al,End_f2

cmp al,1

jz outp

lea bx,buff_tx

mov next_st,bx

lea bx,first

call cut_w ;Чтение заменяемого слова

mov al,End_f2 ;Проверка на конец файла ключей

cmp al,1

jz err7

lea bx,second

call cut_w ;Чтение заменяющего слова

rep3:

mov bx,next_st ;BX-адрес начала след. слова.

push bx

sub bx,offset buff_tx

cmp bx,F_len

jae rep2 ;Если конец файла, идём к след. ключу

pop bx

push bx

call find_r

pop bx

cmp ah,0

jz rep3 ;Если длина слова = 0 то ищем след-е

mov byte ptr third_l,ah

cmp ah,byte ptr first_l

jnz rep3 ;Если длина не = длине ключа, ищем след.

xor al,al

xchg al,ah

mov di,bx ;DI-адрес начала слова

lea si,first ;SI-адрес начала ключа

mov cx,ax ;CX-кол-во букв в словах

cld

repe cmpsb

cmp cx,0

jnz rep3 ;Если слова не совпадают => к следующему

push ax

mov al,byte ptr first_l

cmp al,1

pop ax

jnz nxt

dec di

dec si

mov cx,[di]

cmp cx,[si]

jnz rep3

nxt:

call resize ;Раздвигаем/сдвигаем текст

call repl ;Вставляем слово

jmp rep3 ;Переходим к следующему

outp:

call cr_lf ;Удаление из текста символов CR&LF

call format ;Форматирование текста

mov ah,3ch ;Создаём новый файл

lea dx,file_ou ;С именем 'task3_3.txt

xor cx,cx ;

int 21h

jc err4 ;Если ошибка,идём на обработку

mov Handle3,ax

mov bx,ax

lea dx,buff_tx

mov cx,f_len

mov ah,40h ;Записываем в файл

int 21h

jc err5 ;Если ошибка идём на обработку

jmp end_p

;-----------------------------------------------------------------------------

err1: ; Ошибка открытия 1-го файла

lea dx,mes1

mov ah,09h

int 21h

jmp end_p

err2: ; Ошибка открытия 2-го файла

lea dx,mes2

mov ah,09h

int 21h

jmp end_p

err3: lea dx,mes3 ;Вывод сообщения о большом размере файла

mov ah,09

int 21h

jmp end_p

err4: lea dx,mes4 ;Выв. сообщения об ошибке создания файла

mov ah,09

int 21h

jmp end_p

err5: lea dx,mes5 ;Выв. сообщения об ошибке записи в файл

mov ah,09

int 21h

mov bx,Handle3 ;Закрытие файла

mov ah,3eh

int 21h

jmp end_p

err6: ; Ошибка чтения из 2-го файла

lea dx,mes6

mov ah,09h

int 21h

mov bx,Handle2 ;Закрытие файла

mov ah,3eh

int 21h

jmp end_p

err7: lea dx,mes7

mov ah,09

int 21h

jmp outp

err8: lea dx,mes8

mov ah,09

int 21h

jmp end_p

;-----------------------------------------------------------------------------

;Процедура считывает слово из файла с описателем Handle2 в память начиная с BX,

;занося в [BX+64] длину этого слова и сдвигая указатель к началу след. слова.

cut_w proc near

xor si,si

push bx

rep1:

mov ah,3fh

mov dx,bx

add dx,si

mov bx,handle2

mov cx,1

int 21h ;Читаем 1 символ из файла ключей

pop bx

jc cut_e

cmp ax,0

jz cut_e ;Если достигнут конец файла

mov al,[bx+si]

cmp al,41h

jc end_w ;Если разделитель-идём на завершение

inc si

rep11: push bx

jmp rep1

cut_e: ;Обработка конца файла

push bx

mov bx,Handle2 ;Закрытие файла 2

mov ah,3eh

int 21h

mov end_f2,1

pop bx

mov [bx+64],si

mov ah,[bx+64]

ret

end_w: ; Найден разделитель

mov [bx+64],si

mov ah,[bx+64]

cmp ah,0 ; Если выделенное слово нулевой длины,

jz rep11 ; то продолжаем поиск

ret

;-----------------------------------------------------------------------------

;Процедура ищет с адреса [bx] слово, занося в AH кол-во его букв, и занося

;в ячейку next_st и регистр BX адрес след. слова

find_r proc near

push cx

mov exit,0

mov ah,0

begin:

push bx

sub bx,offset buff_tx

cmp bx,F_len ;Проверяем достигнут ли конец файла

pop bx

ja f_exit

mov al,[bx]

cmp al,41h

jc end_r ; Если разделитель - идём к end_r

cmp exit,1

jz f_exit ; Выход, если BX на позиции след. числа

inc ah ; Увеличиваем счётчик кол-ва цифр

inc bx ; Сдвигаем указатель

jmp begin ; На начало

end_r: inc bx

mov exit,1 ; Разделитель найден, ищём след. слово

jmp begin

f_exit: mov next_st,bx

pop cx

ret

find_r endp

;-------------------------------------------------------------------------------

;Процедура раздвигает или сдвигает текст с позиции [BX] в зависимости от

;значений длин ключа и земеняющего слова.

resize proc near

mov al,byte ptr first_l

mov ah,byte ptr sec_l

cmp al,ah

jc R_up ;Если длина ключа < длины слова => R_up

sub al,ah

xor ah,ah

lea di,buff_tx

add di,bx

add di,first_l

mov si,di ;SI-указ-ет на конец слова+1

sub di,ax ;DI=SI-смещение

cld ;SI и DI будут увеличиваться

lea cx,buff_tx

add cx,f_len

sub cx,si ;В CX-длина перемещаемых байт

push bx

add bx,cx

cmp bx,10240

jnc err8

pop bx

rep movsb

sub f_len,ax

sub next_st,ax

ret

R_up:

sub ah,al

xor al,al

xchg al,ah

lea di,buff_tx

add di,F_len

mov si,di ;SI указ-ет на последний байт текста

add di,ax ;DI=SI+смещение

std ;SI и DI будут уменьшаться

lea cx,buff_tx

add cx,f_len

sub cx,bx ;В CX-количество перемещаемых байт

rep movsb

add f_len,ax

add next_st,ax

ret

resize endp

;------------------------------------------------------------------------------

;Процедура заменяет слово с адреса BX на слово из Second.

repl proc near

lea si,second

mov di,bx

mov cx,sec_l

cld

rep movsb

ret

repl endp

;-----------------------------------------------------------------------------

;Процедура производит удаление из текста, символов CR&LF

cr_lf proc near

lea bx,buff_tx

dec bx

dec bx

add bx,f_len ;BX=конец текста-2

rep4: mov ax,word ptr [bx]

cmp ax,0a0dh

jnz decr ;Если 0a0d не найдено идём на повторение

dec bx

mov al,byte ptr [bx]

cmp al,45

jz del_2d

inc bx

mov [bx],byte ptr 20h ;Помещаем символ пробела

inc bx

mov di,bx

mov si,di

inc si

cld

mov cx,f_len

sub cx,si

rep movsb ;Смещаем весь текст на 1 символ назад

sub f_len,1

decr: dec bx

cmp bx,0

jnz rep4

ret

del_2d:

mov di,bx

mov si,di

inc si

inc si

inc si

cld

mov cx,f_len

sub cx,si

rep movsb

sub f_len,3

dec bx

dec bx

dec bx

cmp bx,0

jnz rep4

ret

cr_lf endp

;------------------------------------------------------------------------------

;Процедура производит форматирование текста, вставляя символы CR&LF

format proc near

lea bx,buff_tx

mov b_point,bx

mov next_st,bx

rep5: mov bx,next_st

push bx

sub bx,offset buff_tx

cmp bx,F_len

pop bx

jae f_end ;Если конец файла => завершение

push bx

call find_r

pop bx

mov cx,next_st ;

sub cx,b_point ;Если прошли > 80 символов, то возвра-

cmp cx,50h ;щаемся к пред. слову и вставляем CR&LF

ja f_ins

jz f_cur

jmp rep5

f_cur: mov bx,next_st

f_ins:

lea di,buff_tx

add di,F_len

mov si,di ;SI указ-ет на последний байт текста

add di,2 ;DI=SI+смещение

std ;SI и DI будут уменьшаться

mov cx,si

sub cx,bx ;В CX-количество перемещаемых байт

inc cx

rep movsb ;Сдвигаем текст вперёд на 2 символа

add f_len,2

mov [bx],byte ptr 0dh ;Вставляем CR

inc bx

mov [bx],byte ptr 0ah ;Вставляем LF

inc bx

mov b_point,bx

mov next_st,bx

jmp rep5

f_end: ret

format endp

;------------------------------------------------------------------------------

end_p:

mov ax,4c00h

int 21h

code ends

end main