Jimmy M.
Jimmy M.

Reputation: 325

End character of user input string

I am writing a program that takes a Roman Numeral (up to 12 characters) and converts it to a decimal value. I am able to do this conversion successfully and read each value character by character, however my value is always 1000 greater than actual when the inputted string is not 12 characters, which I've determined is due to an extra loop through the evaluate subroutine (if no matches are made, it enters the process for converting M = 1000).

I assume it has something to do with the way I reading the user's string when less than 12 characters. It is my understanding that the read string system call code proceeds until it reaches a '\n' character, and converts that character and the rest of its empty space to 0 characters, so checking if the next character is not equal to 0 should work as I do not expect 0 to be in the user's input. I do realize I can fix my code by jumping to tailLoop if no match is made during "evaluate", but I would like to understand why the code I have currently isn't working.

The following code does not contain much of my program (would be quite long to post in full), only enough to understand the logic processes I am trying to use. This is homework in case it flavors how you want to answer the question.

# Program to translate Roman Numerals to decimal values

.data
    numeralString:
        .space 13
# End Strings

.text   # Begin Program
.globl main

main:
    li $v0, 8 # read string from user at next syscall
    la $a0, numeralString
    li $a1, 13
    syscall

    la $t0, numeralString # take input string and store in $t0
    move $t1, $t0 # creating a copy of base register
    lb $t2, 0($t0) # loads first byte (character) into $t2

    jal evaluate # calls evaluate subroutine.  String passed via $t0 (first byte/character specified in $t2)
             # interger value returned via $v1

    li $v0, 1 # print result value from $v1 at next syscall
    move $a0, $v1
    syscall

exit:   # Exit Program in next syscall

    li $v0, 10 # exit program in next syscall
    syscall

evaluate: # matches numeral in string to correct subroutine
    lb $t3, 1($t0)
    beq $t2, 'M', mChar

mChar:
    addi $v1, $v1, 1000
    # beq $t3, 'C', cSlot
    j tailLoop

tailLoop:
    move $t2, $t3 # $t2 now holds next character of string
    addi $t0, $t0, 1
    bnez $t2, evaluate # Go back to evaluate if next character exists
    jr $ra

Upvotes: 0

Views: 1498

Answers (1)

Konrad Lindenbach
Konrad Lindenbach

Reputation: 4961

It is my understanding that the read string system call code proceeds until it reaches a '\n' character, and converts that character and the rest of its empty space to 0 characters

No.

If you look at the spim source code, you'll see that the read_input function which is called in case of a syscall

Simulate[s] the semantics of fgets (not gets) on Unix file.

According to CPlusPlus.com:

A newline character makes fgets stop reading, but it is considered a valid character by the function and included in the string copied to str.

This is confirmed by examing the spim code.

Upvotes: 0

Related Questions