Переписать из файла в новый файл все строки, заканчивающиеся символом "!" - Assembler
Формулировка задачи:
Задание у меня такое (оно же название темы):
Переписать из файла в новый файл все строки, заканчивающиеся символом "!"
Я вот понял, что у меня должен иметься файлик, в котором будет, к примеру, такой вот текст: aaa! bbb ccc! ddd Я хотел узнать, как мне переписать строку, в которой имеется "!" в новый файл? И как его, собственно, определить, что он есть в этой строке?
Я тут уже немного начал делать (открыл файл и считал с него содержимое). Еще вопрос, где будет находиться содержимое файла после прочтения?
.386
dseg segment use16
message1 db 23,21, 'Enter the file path: $'
message2 db 23,21, 'This file not create $'
pathname db 'c:\asm\81.txt', 0
text1 12, 10, 'File open $'
handle dw ?
buf db ?
dseg ends
cseg segment use16
assume cs:cseg,ds:dseg
m1:
mov cx,dseg
mov ds,cx
-------------!!!открытие файла!!!-----------------
mov al, 0
lea dx, pathname
mov ah, 3Dh
int 21h
jc short error
mov ah,9
lea dx,text1
int 21h
--------------------------------------------------
-------------!!!чтение файла!!!-------------------
mov bx, ax
lea dx, buf
mov cx, 0FFFFh
mov ah, 3Fh
int 21h
--------------------------------------------------
error: mov ah,9
lea dx,text1
int 21h
mov al, 7
int 29h
end m1
cseg endsРешение задачи: «Переписать из файла в новый файл все строки, заканчивающиеся символом "!"»
textual
Листинг программы
;== FASM code =======================
org 100h
jmp start
open db 13,10,' Open file: $' ; мессаги..
create db 13,10,'Create file: $' ;
ok db 'OK! $' ;
err db 'ERROR!',7,'$' ;
oldFname db 'oldFile.txt',0 ; файл с данными
newFname db 'newFile.txt',0 ; новый файл
fBuff db 80*25 dup(0) ; буфер для данных (25 строк)
newBuff db 78*1 dup(' '),13,10 ; буфер для записи (1 строка)
fSize dw 0 ; размер файла
handle dw 0 ; ..и его дескриптор.
start:
; Файл с данными =====================================
mov dx,open ;
call message ;
mov ax,3d00h ; Открыть!
mov dx,oldFname ;
int 21h ;
jc error ; ошибка?
xchg ax,bx ; отправляем хэндл в ВХ
mov dx,ok ; мессага OK
call message ;
mov ah,3fh ; Читать содержимое файла,
mov dx,fBuff ; ..в файловый буфер
mov cx,0ffffh ;
int 21h ;
mov [fSize],ax ; сохраняем размер файла
mov ah,3eh ; Закрыть файл!
int 21h ;
; Новый файл =========================================
mov dx,create ;
call message ;
mov ah,3ch ; Создать!
mov cx,20h ; ..c атрибутом R/W
mov dx,newFname ;
int 21h ;
mov [handle],ax ; сохраняем хэндл файла
; Поиск строки =======================================
mov di,fBuff ; где искать
mov al,'!' ; что искать
mov cx,[fSize] ; длина поиска (размер файла)
find: repne scasb ; старт!
jcxz stop ; стоп - если СХ=0
push ax di cx ; иначе: сохраняем позицию поиска
call writeString ; ..и на сравнение/запись
mov al,' ' ; очистим пробелами,
mov di,newBuff ; ..выходной буфер
mov cx,78 ; ..для след.строки
rep stosb ;
pop cx di ax ; возвращаем позицию
jmp find ; ..и продолжаем поиск
; Финальная стадия ====================================
stop: mov ah,3eh ; Закрыть новый файл!
int 21h ;
mov dx,ok ; мессага OK!
call message ;
jmp exit ; ..и на выход
error: ; (обработчик ошибки)
mov dx,err ;
call message ;
exit: ;
xor ax,ax ;
int 16h ;
int 20h ;
;ннннннннннннннннн П Р О Ц Е Д У Р Ы нннннннннннннннннннннннннннннннннннн
;------------------------------------------------------------------------
message: ;
mov ah,9 ; вывод строки на экран
int 21h ;
ret ;
;------------------------------------------------------------------------
writeString: ;
std ; ставим обратный шаг (флаг DF=1)
push cx ; запомним позицию конца (символ "!")
mov al,0Ah ; будем искать 0Аh (справа-налево)
repne scasb ; поиск пока не найдём, или СХ = 0
cld ; ставим прямой шаг (слева-направо)
pop bx ; пизиция конца в ВХ, начала в СХ
sub bx,cx ; расчитываем длину строки,
xchg cx,bx ; ..и ставим её счётчиком для копирования
sub cx,2 ; (коррекция счётчика)
xchg si,di ; SI = адрес источника
add si,2 ; (коррекция источника)
mov di,newBuff ; DI = адрес приёмника
rep movsb ; скопировать строку из SI в DI
mov ah,40h ;<----; Запись в файл!
mov bx,[handle] ;
mov cx,80 ; ..байт для записи
mov dx,newBuff ; что записывать
int 21h ;
ret ;
Объяснение кода листинга программы
Код написан на ассемблере и выполняет следующие действия:
- Открывает старый файл с помощью функции
openи выводит сообщение об успешном открытии или ошибке. - Создает новый файл с помощью функции
createи выводит сообщение об успешном создании или ошибке. - Ищет все строки в старом файле, которые заканчиваются символом
!. Для этого используется функцияfind, которая выполняет поиск строки, начиная с указанного места в файле, и выходит из цикла, когда достигает конца строки или когда находит строку, заканчивающуюся на!. - Записывает найденные строки в новый файл с помощью функции
writeString. - Закрывает старый и новый файлы с помощью функций
closeиexit. Список переменных: - oldFname - строка, содержащая имя старого файла.
- newFname - строка, содержащая имя нового файла.
- fBuff - буфер для чтения данных из старого файла.
- newBuff - буфер для записи данных в новый файл.
- fSize - переменная, содержащая размер старого файла.
- handle - переменная, содержащая дескриптор старого файла. Список функций:
- open - открывает старый файл и выводит сообщение об успешном открытии или ошибке.
- create - создает новый файл и выводит сообщение об успешном создании или ошибке.
- message - выводит сообщение на экран.
- find - ищет строку в файле.
- writeString - записывает строку в новый файл.
- close - закрывает старый и новый файлы.
- exit - завершает программу.