如何处理MARS读整数系统调用中的非数字用户输入?
解决MIPS停车场程序非整数输入崩溃问题
嘿,我之前写MIPS程序的时候也踩过这个坑!你用的li $v0,5对应的是MIPS的读整数系统调用(syscall 5),这个调用有个很麻烦的特性:它只接受合法的十进制整数输入,如果用户输入字母、符号这类非整数内容,操作系统会直接触发异常终止程序,根本不给你处理错误的机会。
问题根源
syscall 5本身没有错误返回机制,它默认用户会输入合法整数。一旦输入不符合格式,系统就会直接终止进程,这就是你看到程序突然退出的原因。
解决方案:先读字符串再手动校验转换
要解决这个问题,我们得换一种输入方式:先用**读字符串系统调用(syscall 8)**获取用户输入的全部内容,然后自己写一个函数来校验输入是否为整数,并将合法的字符串转换成整数。这样就能完全掌控错误处理流程,不会让程序直接崩溃。
下面是完整的改进代码示例:
数据段定义
.data buffer: .space 20 # 存储用户输入的字符串缓冲区 prompt: .asciiz "请输入1(停车)或2(离场):" error_msg: .asciiz "输入无效!请输入整数1或2\n"
主程序与核心逻辑
.text main: # 提示用户输入 li $v0, 4 la $a0, prompt syscall # 读取用户输入的字符串(最多20字符) li $v0, 8 la $a0, buffer li $a1, 20 syscall # 调用字符串转整数并校验的函数 la $a0, buffer jal str_to_int move $t0, $v0 # 保存转换后的整数结果 # 检查转换是否失败(返回-1表示非法输入) bltz $t0, invalid_input # 校验输入是否为1或2 li $t1, 1 beq $t0, $t1, park li $t1, 2 beq $t0, $t1, exit # 输入是整数但不是1/2,同样提示错误 j invalid_input invalid_input: # 输出错误提示 li $v0, 4 la $a0, error_msg syscall j main # 回到输入步骤,让用户重新输入 # 字符串转整数函数: # 输入:$a0 = 字符串地址 # 输出:$v0 = 转换后的整数(非法输入返回-1) str_to_int: li $v0, 0 # 初始化结果为0 li $t2, 0 # 非法标记:0=合法,1=非法 loop: lb $t1, ($a0) # 读取当前字符 beq $t1, '\n', end_str # 遇到换行符结束处理 beq $t1, '\0', end_str # 遇到字符串结束符结束处理 # 检查字符是否为0-9的数字 blt $t1, '0', mark_invalid bgt $t1, '9', mark_invalid # 计算数值:结果 = 结果*10 + (当前字符 - '0') mul $v0, $v0, 10 sub $t1, $t1, '0' add $v0, $v0, $t1 addi $a0, $a0, 1 # 指针移到下一个字符 j loop mark_invalid: li $t2, 1 # 标记输入非法 # 跳过剩余字符,避免影响下一次输入 skip_rest: lb $t1, ($a0) beq $t1, '\n', end_str beq $t1, '\0', end_str addi $a0, $a0, 1 j skip_rest end_str: bne $t2, 0, return_error jr $ra return_error: li $v0, -1 jr $ra # 停车逻辑段 park: # 这里编写你的停车处理代码 # ... j main # 处理完回到主菜单 # 离场/退出逻辑段 exit: # 这里编写你的离场处理代码,或者直接退出 li $v0, 10 syscall
关键改进点
- 用
syscall 8读取字符串,确保无论用户输入什么,程序都不会直接崩溃 - 自定义的
str_to_int函数负责校验输入合法性,并完成字符串到整数的转换 - 错误处理分支会提示用户重新输入,而不是直接终止程序
内容的提问来源于stack exchange,提问作者Lutfi
相关产品推荐
相关产品推荐

