2010-04-04 4 views
5

J'écris un code d'assemblage MIPS qui demandera à l'utilisateur le nom du fichier et il produira des statistiques sur le contenu du fichier.lire le nom de fichier de l'entrée de l'utilisateur dans l'assemblage MIPS

Cependant, lorsque je code dur le nom du fichier dans une variable depuis le début, cela fonctionne très bien, mais lorsque je demande à l'utilisateur d'entrer le nom du fichier, cela ne fonctionne pas. Après un débogage, j'ai découvert que le programme ajoute 0x00 char et 0x0a char (vérifier asciitable.com) à la fin de l'entrée de l'utilisateur dans la mémoire et c'est pourquoi il n'ouvre pas le fichier basé sur l'entrée de l'utilisateur

Quelqu'un at-il une idée sur la façon de se débarrasser de ces caractères supplémentaires, ou comment ouvrir le fichier après avoir obtenu son nom de l'utilisateur ??

voici mon code complet (il fonctionne très bien à l'exception du nom de fichier de chose de l'utilisateur, et tout le monde est libre de l'utiliser à des fins qu'il/elle veut):

 .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 

Note: I « utilise MARS Simulator, si cela fait différent

Mise à jour: J'ai résolu le problème en écrivant et en appelant la procédure suivante:

 
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 

Répondre

4

carac r 10 (0xa) est le code Ascii pour linefeed, que de nombreux systèmes d'exploitation * nix utilisent pour le terminateur de ligne. Cela ne devrait pas faire partie du nom de fichier. Débarrassez-le. En outre, ces systèmes d'exploitation utilisent 0 pour un terminateur de chaîne. Il devrait être à la fin du nom de fichier, sauf si l'appel ouvert prend un nombre de caractères paramètre.

La solution est de prendre la réponse de l'utilisateur, trouver le caractère 10 et le remplacer par zéro. Utilisez le résultat comme nom de fichier pour l'ouvrir.

+0

Merci J'ai résolu le problème, en écrivant et en appelant la procédure suivante

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

Questions connexes