чтение имени файла из пользовательского ввода в сборке MIPS

Я пишу ассемблерный код MIPS, который запрашивает у пользователя имя файла и выдает некоторую статистику о содержимом файла.

Однако, когда я жестко кодирую имя файла в переменной с самого начала, оно работает нормально, но когда я прошу пользователя ввести имя файла, оно не работает.

после некоторой отладки я обнаружил, что программа добавляет 0x00 char и 0x0a char (проверьте asciitable.com) в конце пользовательского ввода в память и поэтому не открывает файл на основе пользовательского ввода.

кто-нибудь знает, как избавиться от этих лишних символов или как открыть файл после получения его имени от пользователя ??

вот мой полный код (он работает нормально, за исключением имени файла от пользователя, и любой может использовать его для любых целей):

        .data
fin:   .ascii ""      # filename for input
msg0:   .asciiz "aaaa"
msg1:   .asciiz "Please enter the input file name:"
msg2:   .asciiz "Number of Uppercase Char: "
msg3:   .asciiz "Number of Lowercase Char: "
msg4:   .asciiz "Number of Decimal Char:   "
msg5:   .asciiz "Number of Words:          "
nline:  .asciiz "\n"
buffer: .asciiz ""
        .text

#-----------------------
    li $v0, 4
    la $a0, msg1
    syscall

    li $v0, 8
    la $a0, fin
    li $a1, 21
    syscall

    jal fileRead            #read from file

    move $s1, $v0           #$t0 = total number of bytes

    li $t0, 0   # Loop counter
    li $t1, 0   # Uppercase counter
    li $t2, 0   # Lowercase counter
    li $t3, 0   # Decimal counter
    li $t4, 0   # Words counter

loop:
    bge $t0, $s1, end           #if end of file reached OR if there is an error in the file
    lb $t5, buffer($t0)         #load next byte from file

    jal checkUpper              #check for upper case
    jal checkLower              #check for lower case
    jal checkDecimal            #check for decimal
    jal checkWord               #check for words


    addi $t0, $t0, 1            #increment loop counter

j loop

end:

    jal output
    jal fileClose

    li $v0, 10
    syscall







fileRead:
    # Open file for reading
    li   $v0, 13       # system call for open file
    la   $a0, fin      # input file name
    li   $a1, 0        # flag for reading
    li   $a2, 0        # mode is ignored
    syscall            # open a file 
    move $s0, $v0      # save the file descriptor 

    # reading from file just opened
    li   $v0, 14       # system call for reading from file
    move $a0, $s0      # file descriptor 
    la   $a1, buffer   # address of buffer from which to read
    li   $a2, 100000   # hardcoded buffer length
    syscall            # read from file

jr $ra

output:
    li $v0, 4
    la $a0, msg2
    syscall

    li $v0, 1
    move $a0, $t1
    syscall

    li $v0, 4
    la $a0, nline
    syscall

    li $v0, 4
    la $a0, msg3
    syscall

    li $v0, 1
    move $a0, $t2
    syscall

    li $v0, 4
    la $a0, nline
    syscall

    li $v0, 4
    la $a0, msg4
    syscall

    li $v0, 1
    move $a0, $t3
    syscall

    li $v0, 4
    la $a0, nline
    syscall

    li $v0, 4
    la $a0, msg5
    syscall

    addi $t4, $t4, 1
    li $v0, 1
    move $a0, $t4
    syscall

jr $ra

checkUpper:
    blt $t5, 0x41, L1           #branch if less than 'A'
    bgt $t5, 0x5a, L1           #branch if greater than 'Z'
    addi $t1, $t1, 1            #increment Uppercase counter

    L1:
jr $ra

checkLower:
    blt $t5, 0x61, L2           #branch if less than 'a'
    bgt $t5, 0x7a, L2           #branch if greater than 'z'
    addi $t2, $t2, 1            #increment Lowercase counter

    L2:
jr $ra

checkDecimal:
    blt $t5, 0x30, L3           #branch if less than '0'
    bgt $t5, 0x39, L3           #branch if greater than '9'
    addi $t3, $t3, 1            #increment Decimal counter

    L3:
jr $ra

checkWord:
    bne $t5, 0x20, L4           #branch if 'space'
    addi $t4, $t4, 1            #increment words counter

    L4:
jr $ra

fileClose:
    # Close the file 
    li   $v0, 16       # system call for close file
    move $a0, $s0      # file descriptor to close
    syscall            # close file
jr $ra

Примечание. Я использую симулятор MARS, если это имеет значение.

Обновление: я решил проблему, написав и вызвав следующую процедуру:

nameClean:
    li $t0, 0       #loop counter
    li $t1, 21      #loop end
clean:
    beq $t0, $t1, L5
    lb $t3, fin($t0)
    bne $t3, 0x0a, L6
    sb $zero, fin($t0)
    L6:
    addi $t0, $t0, 1
j clean
L5:
jr $ra


person Hassan Al-Jeshi    schedule 04.04.2010    source источник


Ответы (1)


Символ 10 (0xa) — это код перевода строки в кодировке Ascii, который многие операционные системы *nix используют для обозначения конца строки. Оно не должно быть частью имени файла. Просто раздень его. Кроме того, такие операционные системы используют 0 для обозначения конца строки. Он должен быть в конце имени файла, если вызов open не принимает параметр количество символов.

Решение состоит в том, чтобы взять ответ пользователя, найти символ 10 и заменить его нулем. Используйте результат в качестве имени файла для открытия.

person wallyk    schedule 04.04.2010
comment
Спасибо, я решил проблему, написав и вызвав следующую процедуру ‹pre›‹code› nameClean: li $t0, 0 #loop counter li $t1, 21 #loop end clean: beq $t0, $t1, L5 lb $t3, fin($t0) bne $t3, 0x0a, L6 sb $zero, fin($t0) L6: addi $t0, $t0, 1 j clean L5: jr $ra ‹/code›‹/pre› - person Hassan Al-Jeshi; 05.04.2010