尽管FlushConsoleInputBuffer MASM

时间:2019-06-07 20:58:35

标签: winapi assembly input x86 buffer

我编写了一个处理数组的程序,我需要检查输入的正确性。如果您与数字和字母一起输入,那么输入命令会循环并且不允许您输入数据,我决定在每次输入之前对缓冲区进行清理,但是问题仍然存在

S1:invoke   WriteConsole, h_output, ADDR ComSizeMas, Len_ComSize, ADDR nWrite, 0 
   invoke FlushConsoleInputBuffer,h_input
   invoke      crt_scanf,  ADDR format_size_buf, ADDR Size_buf     
   CMP Size_buf,1
   JL S1
   CMP Size_buf,100
   JG S1

1 个答案:

答案 0 :(得分:1)

scanf[_s]将数据读取到内部crt缓冲区。调用FlushConsoleInputBuffer对此无效。相反,我们需要在stdin流上调用fflush

  

如果打开流供输入,则fflush清除流的内容   缓冲

因此在 c / c ++ 代码中,我们需要fflush(__iob_func())调用。

演示示例 c / c ++

ULONG __cdecl GetNumberc()
{
    ULONG n;
    while (!scanf_s("%u", &n))
    {
        if (fflush(__iob_func())) break;

        printf("invalid number\n");
    }

    return n;
}

用于 x86 asm

extern __imp__fflush : DWORD, 
       __imp____iob_func : DWORD, 
       __imp__scanf_s : DWORD,
       __imp__printf : DWORD

.const
format_number DB "%u",0
invalid_number DB "invalid number",10,0

.code

_GetNumber proc
    sub esp,4
@@0:
    push esp
    push offset format_number
    call __imp__scanf_s
    add esp,8
    test eax,eax
    jnz @@1

    call __imp____iob_func
    push eax
    call __imp__fflush
    add esp,4
    test eax,eax
    jnz @@1
    push offset invalid_number
    call __imp__printf
    add esp,4
    jmp @@0
@@1:
    mov eax,[esp]
    add esp,4
    ret
_GetNumber endp

用于 x64 asm

extern __imp_fflush : QWORD, 
       __imp___iob_func : QWORD, 
       __imp_scanf_s : QWORD,
       __imp_printf : QWORD

.const
format_number DB "%u",0
invalid_number DB "invalid number",10,0

.code

GetNumber proc
    sub rsp,28h
@@0:
    lea rdx,[rsp+30h]
    lea rcx,format_number
    call __imp_scanf_s
    test eax,eax
    jnz @@1

    call __imp___iob_func
    mov rcx,rax
    call __imp_fflush
    test eax,eax
    jnz @@1
    lea rcx,invalid_number
    call __imp_printf
    jmp @@0
@@1:
    mov eax,[rsp+30h]
    add rsp,28h
    ret
GetNumber endp