每当我在循环中先前输入可接受的数字之后尝试在我的scanf中输入字母或符号以查找无符号整数时,它都会连续输入先前的数字,从而导致程序无限期地运行。我该如何解决?这是我编写的示例代码:
[bits 32]
global _main
extern _scanf
extern _printf
section .data
prompt_number db "Please select a number. Enter 0 to escape. ", 0
display_number db "You entered %u. ", 0
number_fmt db "%u", 0
number_input dd 0
section .bss
section .text
_main:
push ebp
mov ebp, esp
and esp, 0xfffffff0
_Label:
sub esp, 16
mov dword[esp], prompt_number
call _printf
add esp, 16
sub esp, 16
mov dword[esp], number_fmt
mov dword[esp+4], number_input
call _scanf
add esp, 16
sub esp, 16
mov dword[esp], display_number
mov eax, [number_input]
mov dword[esp+4], eax
call _printf
add esp, 16
cmp dword[number_input], 0
jne _Label
mov esp, ebp
mov eax, 1
pop ebp
ret
答案 0 :(得分:0)
这与scanf
在这种情况下的工作方式有关,一种解决方案是从C移植针对Good way to flush scanf buffer when invalid entry entered的建议解决方案之一。
我的理解是,如果scanf
无法将输入映射到格式字符串(在这种情况下,尝试将任意字符转换为无符号整数),则它放弃但不会从中删除任何内容输入缓冲区。因此,在这种情况下,随后对scanf
的调用仅使用缓冲区中当前的内容。
以下是尝试移植第一个解决方案的快速尝试(使用getchar
消耗缓冲区)。我不能保证它的质量。基本上这是我第一次进行程序设计组装:
[bits 32]
global _main
extern _getchar
extern _scanf
extern _printf
section .data
prompt_number db "Please select a number. Enter 0 to escape. ", 0
display_number db "You entered %u. ", 0
scan_error db "Error scanning input. ", 0
number_fmt db "%u", 0
number_input dd 0
section .bss
section .text
_main:
push ebp
mov ebp, esp
and esp, 0xfffffff0
_Label:
sub esp, 16
mov dword[esp], prompt_number
call _printf
add esp, 16
sub esp, 16
mov dword[esp], number_fmt
mov dword[esp+4], number_input
call _scanf
add esp, 16
cmp eax, 0
jne _ScanSuccess
_ScanError:
sub esp, 16
mov dword[esp], scan_error
call _printf
add esp, 16
_ScanErrorConsumeInput:
sub esp, 16
call _getchar
add esp, 16
cmp eax, -1 ; most common value indicating end-of-file
je _Label
cmp eax, 10 ; newline in ASCII
je _Label
jmp _ScanErrorConsumeInput
_ScanSuccess:
sub esp, 16
mov dword[esp], display_number
mov eax, [number_input]
mov dword[esp+4], eax
call _printf
add esp, 16
cmp dword[number_input], 0
jne _Label
_Return:
mov esp, ebp
mov eax, 1
pop ebp
ret