DOSBox环境下汇编语言实现TXT文件单词计数功能求助
汇编程序单词计数功能修复求助
我是汇编语言编程初学者,当前需要完成以下任务:
- 提示用户输入TXT文件名
- 检查文件是否存在:若存在则统计文件内单词数并显示结果;若不存在则报错并重新提示输入
目前已实现文件读取部分,但单词计数逻辑存在问题,附上在DOSBox下编译运行的现有代码,请求帮助完善代码以完成任务。
现有代码
.model small .stack 200h .data prompt db 10,13, "Enter the file name: $" filename db 100,102 dup("$") filehandle dw ? open_msg db 10,13, "File successfully opened! $" open_error_msg db 10,13,"File cannot be opened! $" count_msg db 10, 13, 'The number of words in the file: $' word1 db 1 .code start: ;Initiate mov ax,seg open_msg mov ds,ax ; Display Prompt message === retry: mov dx,offset prompt mov ah,9 int 21h ; Enter Filename === mov dx,offset filename mov ah,10 int 21h mov bl,filename[1] cmp bl,8 ja retry jmp store store: mov [bx+filename+2],0 ;Open the file open: mov ah, 3Dh mov dx, offset [filename+2] mov al,2 int 21h jc retry ;if file successfully opened, save the filehandle mov [filehandle],ax mov ah,9 mov dx,offset open_msg; display file opened succesfully int 21h jmp count_loop error_when_open: mov ah,9 mov dx,offset open_error_msg int 21h ; PART for Counts the number of words in the file ; continue the PART for Counts the number of words in the file here count_words: mov cx, 0 mov si, 0 count_loop: mov ah, 3fh mov bx, filehandle mov cx, 1 mov dx, offset word1 int 21h cmp ax, 1 je increment cmp ax, 0 je end_count mov al, word1 cmp al, ' ' je increment jmp count_loop increment: inc cx jmp count_loop end_count: mov ah, 09h mov dx, offset count_msg int 21h mov dx, cx add dx, 48 mov ah, 02h int 21h jmp close close: mov ah,3eh mov dx,filehandle int 21h mov ah,4ch int 21h end start
修复后的代码
.model small .stack 200h .data prompt db 10,13,"Enter the file name: $" filename db 100, 102 dup("$") ; DOS输入缓冲区:[0]=最大长度, [1]=实际长度, [2..]=输入字符 filehandle dw ? open_msg db 10,13,"File successfully opened! $" open_error_msg db 10,13,"File cannot be opened! $" count_msg db 10,13,"The number of words in the file: $" current_char db ? is_in_word db 0 ; 状态标志:0=当前在空白字符,1=当前在单词中 count_buffer db 5 dup('$') ; 存储转换后的十进制数字字符串 .code start: ; 初始化数据段 mov ax, @data mov ds, ax retry: ; 提示输入文件名 mov dx, offset prompt mov ah, 9 int 21h ; 读取文件名(DOS功能调用10) mov dx, offset filename mov ah, 10 int 21h ; 处理输入的文件名:添加字符串终止符 mov bl, filename[1] ; 获取实际输入长度 cmp bl, 0 ; 禁止空输入 je retry mov byte ptr [filename + 2 + bx], 0 ; 在输入字符末尾加0 ; 以只读方式打开文件(AL=0),原代码AL=2是读写,统计不需要写权限 mov ah, 3Dh mov dx, offset filename + 2 mov al, 0 int 21h jc open_failed ; 进位标志置位表示打开失败 ; 打开成功,保存文件句柄并提示 mov [filehandle], ax mov dx, offset open_msg mov ah, 9 int 21h ; 初始化单词计数相关变量 mov cx, 0 ; cx存储单词数 mov byte ptr [is_in_word], 0 ; 初始状态:不在单词中 count_loop: ; 读取一个字符(DOS功能调用3F) mov ah, 3Fh mov bx, [filehandle] mov cx, 1 mov dx, offset current_char int 21h cmp ax, 0 ; ax=0表示文件读取完毕 je end_count cmp ax, 1 ; ax=1表示成功读取一个字符 jne count_loop ; 读取异常,继续循环 ; 判断当前字符是否为空白字符(空格、制表符、换行、回车) mov al, current_char cmp al, ' ' je handle_whitespace cmp al, 09h ; Tab键 je handle_whitespace cmp al, 0Ah ; 换行 je handle_whitespace cmp al, 0Dh ; 回车 je handle_whitespace ; 当前字符是非空白字符 mov al, [is_in_word] cmp al, 0 je start_new_word ; 之前不在单词中,现在开始新单词 jmp count_loop ; 已经在单词中,继续读取下一个字符 handle_whitespace: ; 当前字符是空白字符,标记为不在单词中 mov byte ptr [is_in_word], 0 jmp count_loop start_new_word: ; 开始新单词,计数+1,标记为在单词中 inc cx mov byte ptr [is_in_word], 1 jmp count_loop end_count: ; 显示计数提示信息 mov dx, offset count_msg mov ah, 9 int 21h ; 将cx中的数字转换为十进制字符串并显示 mov ax, cx mov si, offset count_buffer + 4 ; 从缓冲区末尾开始填充 mov bx, 10 ; 除数为10 convert_loop: xor dx, dx ; dx清零,准备除法 div bx ; ax = ax / 10, dx = ax % 10 add dl, '0' ; 余数转换为ASCII字符 mov [si], dl dec si cmp ax, 0 jne convert_loop ; 显示转换后的数字字符串 mov dx, si inc dx ; 指向第一个有效数字 mov ah, 9 int 21h ; 关闭文件并退出 close_file: mov ah, 3Eh mov bx, [filehandle] int 21h exit_program: mov ah, 4Ch int 21h open_failed: ; 显示打开失败提示,然后重新输入 mov dx, offset open_error_msg mov ah, 9 int 21h jmp retry end start
关键修改说明
- 核心计数逻辑修复:
- 新增
is_in_word状态标志,区分当前处于空白字符还是单词中 - 仅当从空白字符切换到非空白字符时,才递增单词计数,符合标准单词定义
- 支持多种空白字符(空格、制表符、换行、回车)
- 新增
- 功能完善:
- 修复文件打开失败的报错流程:先显示错误信息再重试输入
- 实现多位数数字显示:新增数字转字符串逻辑,支持任意非负整数计数
- 优化文件打开模式:使用只读模式(AL=0)替代原有的读写模式,更符合统计需求
- 代码规范与bug修复:
- 用标准的
mov ax, @data初始化数据段 - 修复文件名终止符的添加逻辑,避免地址计算错误
- 修复关闭文件的参数错误:DOS功能调用3E需用
bx传递文件句柄 - 移除无用标签,优化代码流程
- 用标准的
内容的提问来源于stack exchange,提问作者MuuN
相关产品推荐
相关产品推荐

