Изменение строки (расширение имени файла)
Я здесь новенький. Вот в чем дело: мне нужно прочитать имя файла и затем убедиться, что оно заканчивается на ".IN", если нет, мне нужно добавить его, чтобы открыть файл. После этого мне нужно создать файл с тем же именем файла, но заканчивающийся на ".OUT", заменив ".IN"
GetFileName proc near
lea bx,MsgEnterFilename
call printf_s ;It prints the string above
mov ah,0ah
lea dx,FileNameBuffer
mov byte ptr FileNameBuffer,100
int 21h
lea si,FileNameBuffer+2
lea di,FileName
mov cl,FileNameBuffer+1
mov ch,0
mov ax,ds
mov es,ax
rep movsb
mov byte ptr es:[di],0 ;Puts a '\0' at the end
ret
GetFileName endp
fileNameInfo proc near ;Puts ".IN" and ".OUT"
lea si, FileName
lea di, FileNameCopy
mov cx, MAXSTRING ; MAXSTRING is set to 256, yeah, I am copying beyond the string end
rep movsb
; Search for ".IN"
mov si, 0
start_filename_length:
mov al, FileNameCopy[si]
cmp al, 0
je end_filename_length
inc FileNameLength
inc FileNameLengthAux
add si, 1
jmp start_filename_length
end_filename_length:
sub FileNameLengthAux, 2 ; To begin the test in the last 3 bytes (".IN")
mov si, word ptr FileNameLengthAux
cmp FileNameCopy[si], "."
je test_i
jmp no_extension
test_i:
inc si
mov si, word ptr FileNameLengthAux
cmp FileNameCopy[si], "I"
je test_n
cmp FileNameCopy[si], "i"
je test_n
jmp no_extension
test_n:
inc si ; last byte
mov si, word ptr FileNameLengthAux
cmp FileNameCopy[si], "N"
je correct_extension
cmp FileNameCopy[si], "n"
je correct_extension
;jmp no_extension
no_extensao: ;wrong extension counts as no extension
inc FileNameLengthAux ;goes to '\0' position
mov si, word ptr FileNameLengthAux
mov FileNameCopy[si], "."
inc si
mov FileNameCopy[si], "O"
inc si
mov FileNameCopy[si], "U"
inc si
mov FileNameCopy[si], "T"
inc si
mov FileNameCopy[si], 0 ;End the string
lea si, FileNameCopy
lea di, FileNameOut
mov cx, MAXSTRING ; copy 256 bytes
rep movsb
jmp return_filename_info
correct_extension: ;copyies till the "."
mov bl, FileNameLengthAux
mov FileNameLength, bl
sub FileNameLength, 2
lea si, FileNameCopy
lea di, FileNameOut
mov ch, 0
mov cl, FileNameLengthAux
rep movsb
mov si, word ptr FileNameLengthAux ; it is on "." position
inc si
mov FileNameOut[si], "O"
inc si
mov FileNameOut[si], "U"
inc si
mov FileNameOut[si], "T"
inc si
mov FileNameOut[si], 0 ;End the string
;jmp return_filename_info
return_filename_info:
ret
fileNameInfo endp
Спасибо за помощь =D
2 ответа
sub FileNameLengthAux, 2 ; To begin the test in the last 3 bytes (".IN")
Это знаменитый выход на одну ошибку! Вам нужно вычесть 3.
Проверьте это на примере. Если имя файла было "A.IN", длина будет 4, и вы захотите начать искать "." символ в смещении SI=1
, Посчитайте: 4 - 3 = 1.
test_i: inc si mov si, word ptr FileNameLengthAux
Почему вы уничтожаете (правильно) увеличенное значение для SI
?
test_i: inc si mov si, word ptr FileNameLengthAux
Та же проблема здесь.
mov bl, FileNameLengthAux mov FileNameLength, bl sub FileNameLength, 2
Как вы ожидаете, что это даст правильный окончательный FileNameLength?
FileNameLengthAux уже был меньше исходной длины (вы вычитали 2), а здесь вы делаете его еще меньше (вычитая еще 2)!
Все, что вам нужно, это вернуть длину, которая ровно на 1 больше, чем вы начали.
Если ваша программа не нашла расширение (".IN"), вы вообще не обновляете FileNameLength. Просто добавьте 4, так как это длина добавленного ".OUT".
Звонки в основной программе PS.: Извините, комментарии на португальском
;Constants
AscUpi equ "I"
AscLowi equ "i"
AscUpn equ "N"
AscLown equ "n"
AscUpo equ "O"
AscLowo equ "o"
AscUpu equ "U"
AscLowu equ "u"
AscUpt equ "T"
AscLowt equ "t"
AscDot equ "."
call GetFileName
call GetFileNameLength
call VerifyFileName
call GenFileNameOut
VerifyFileName proc near
mov dx, FileNameLength
mov FileNameLengthAux, dx ; SI considera FileName[0] como sendo a 1a posição, como vetores em C
sub FileNameLengthAux, 3 ;FileNameLength - 3 -> posição do . em ".IN"
mov si, FileNameLengthAux ;"."
;mov dx, "."
cmp FileNameIn[si], AscDot
je testa_i
jmp no_extension
testa_i:
inc si ;FileNameLength - 2 -> posição do I em ".IN" ;"i" ou "I"
;mov dx, "I"
cmp FileNameIn[si], AscUpi
je testa_n
;mov dx, "i"
cmp FileNameIn[si], AscLowi
je testa_n
jmp no_extension
testa_n:
inc si ;FileNameLength - 1 -> posição do N em ".IN" ;"n" ou "N"
;mov dx, "N"
cmp FileNameIn[si], AscUpn
je right_extension
;mov dx, "n"
cmp FileNameIn[si], AscLown
je right_extension
jmp no_extension
no_extension: ;Inclui extensao errada, caso seja entrado 123.abc, será transformado em 123.abc.in (.in são os últimos 3 caracteres)
mov dx, FileNameLength
mov FileNameLengthAux, dx
sub FileNameLengthAux, 1
mov si, FileNameLengthAux
inc si
;mov dx, "."
mov byte ptr FileNameIn[si], AscDot
inc FileNameLength ; Ajusta o FileNameLength somando os 3 caracteres que acabaram de ser adicionados
inc si
;mov dx, "I"
mov byte ptr FileNameIn[si], AscUpi ; No PDF está especificado '.IN'
inc FileNameLength ; Ajusta o FileNameLength somando os 3 caracteres que acabaram de ser adicionados
inc si
;mov dx, "N"
mov byte ptr FileNameIn[si], AscUpn
inc FileNameLength ; Ajusta o FileNameLength somando os 3 caracteres que acabaram de ser adicionados
inc si
mov FileNameIn[si], 0 ; Fecha a String do nome de arquivo
;jmp right_extension
right_extension:
;FILENAMEIN ESTA CORRETO
ret
VerifyFileName endp
GenFileNameOut proc near
;O nome do arquivo de entrada está correto agora, e o tamanho foi atualizado caso tenha sido necessário
;Copiar o FileNameIn para FileNameOut e fazer os ajustes (.IN -> .OUT)
mov cx, FileNameLength
lea si, FileNameIn
lea di, FileNameOut
rep movsb ; Cópia de strings
;agora FileNameOut = FileNameIn
mov ax, FileNameLength
mov FileNameLengthAux, ax
sub FileNameLengthAux, 2 ; Vai para a posição do "I" em ".IN"
mov si, FileNameLengthAux
mov byte ptr FileNameOut[si], "O" ; Subtitui o 'I' por 'O'
inc si
mov byte ptr FileNameOut[si], "U" ; Subtitui o 'N' por 'U'
inc si
mov byte ptr FileNameOut[si], "T" ; Subtitui o 0 por 'T'
inc si
mov byte ptr FileNameOut[si], 0 ; Subtitui o 0 por 0
;FILENAMEOUT ESTA CORRETO
;call NewLine
;lea bx, FileNameOut
;call printf_s
;FileNameOut está pronto
;jmp return_filename_out
return_filename_out:
ret
GenFileNameOut endp
GetFileNameLength proc near
mov si, 0 ;primeira posicao da string
inicio_filename_length:
mov al, FileNameIn[si]
cmp al, 0
je fim_filename_length
inc FileNameLength
inc FileNameLengthAux ;Cópia de FileNameLength
inc si
;add si, 1
jmp inicio_filename_length
fim_filename_length:
ret
GetFileNameLength endp