Изменение строки (расширение имени файла)

Я здесь новенький. Вот в чем дело: мне нужно прочитать имя файла и затем убедиться, что оно заканчивается на ".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
Другие вопросы по тегам