You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MIPS(MARS环境)读取文本文件存储为字符串数组的问题

问题根因

Windows系统的文本文件用\r\n(ASCII码13、10)作为换行分隔符,而MARS的4号字符串打印系统调用,只会在遇到\0(ASCII码0,空终止符)时才停止输出。你当前代码只做了文件全量读取,没有把单词之间的换行符替换为空终止符,也没有拆分每个单词的起始地址,直接从缓冲区头部打印自然会把后续所有内容全部输出。

现有代码还存在两个参数错误:

  • 预留的inputBuffer空间是14976字节,但读文件时传入的最大读取长度是14946,参数不匹配
  • 没有存储每个单词的起始地址,无法单独索引单个字符串

注意:MARS中14号读文件系统调用不会自动在读取内容末尾加空终止符,不做处理的话打印字符串会读到缓冲区外的垃圾值

修复方案
  1. 读完文件后遍历整个输入缓冲区,把所有\r、\n字符替换为\0,实现每个单词的空终止符分隔
  2. 额外预留一块指针数组空间,遍历过程中记录每个单词的起始地址存入数组,后续要访问第n个单词,直接取数组中第n项的地址即可
  3. 修正读文件的长度参数,和预留缓冲区大小对齐,避免读溢出
修正后可运行代码
.data
dictionary:     .asciiz "dictionary.txt"
inputBuffer:    .space  14976   # 预留2496个单词的存储空间
wordArray:      .space  9984    # 单词指针数组,每个地址占4字节,共可存2496个单词地址

.text
openDictionary:
    # 打开字典文件
    la $a0, dictionary
    addi $a1, $zero, 0
    addi $a2, $zero, 0
    li $v0, 13
    syscall
    move $t0, $v0       # 保存文件描述符

    # 读取文件内容到缓冲区
    li $v0, 14
    move $a0, $t0
    la $a1, inputBuffer
    addi $a2, $zero, 14976  # 读取长度和缓冲区大小对齐
    syscall
    move $t1, $v0       # 保存实际读取到的字节总数

    # 关闭文件
    li $v0, 16
    move $a0, $t0
    syscall

    # 遍历缓冲区:替换换行符为\0,同时构建单词指针数组
    la $t0, inputBuffer # t0存当前遍历到的缓冲区地址
    la $t2, wordArray   # t2存当前指针数组的写入位置
    addi $t3, $zero, 0  # t3存已处理的字节计数
    addi $t5, $zero, 1  # t5为标记位:1表示下一个普通字符是新单词的开头

process_loop:
    beq $t3, $t1, process_end  # 所有字节处理完成则退出循环
    lb $t4, 0($t0)             # 读取当前位置的字节

    # 判断当前字节是否为换行符
    beq $t4, 13, replace_newline
    beq $t4, 10, replace_newline

    # 当前是普通单词字符,如果是单词开头就把地址存入指针数组
    beq $t5, $zero, next_char
    sw $t0, 0($t2)
    addi $t2, $t2, 4
    addi $t5, $zero, 0
    j next_char

replace_newline:
    sb $zero, 0($t0)           # 把换行符替换为空终止符
    addi $t5, $zero, 1         # 标记下一个普通字符是新单词开头

next_char:
    addi $t0, $t0, 1
    addi $t3, $t3, 1
    j process_loop

process_end:
    # 测试:打印第一个单词
    li $v0, 4
    la $t0, wordArray
    lw $a0, 0($t0)  # 取第1个单词地址,要打印第n个单词则取偏移量为4*(n-1)的地址即可
    syscall

    jr $ra
运行效果

运行上述代码后,只会输出第一个单词abed,不会连带输出后续内容。需要访问其他单词时,只需要修改指针数组的访问偏移量即可,比如访问第二个单词就用lw $a0, 4($t0),第三个用lw $a0, 8($t0),以此类推。

内容的提问来源于stack exchange,提问作者Jacob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 17:39:22