[英]reading the file name from user input in MIPS assembly
我正在編寫一個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 Simulator,如果這有任何不同
更新:我已通過編寫並調用以下過程解決了該問題:
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
字符10(0xa)是換行符的Ascii代碼,許多* nix操作系統用於行終止符。 它不應該是文件名的一部分。 把它脫掉。 此外,這種操作系統使用0作為字符串終止符。 它應該在文件名的末尾,除非打開調用需要多個字符參數。
解決方案是獲取用戶的回復,找到字符10並將其替換為零。 使用結果作為文件名打開。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.