Входной буфер хранит старый ввод, несмотря на FlushConsoleInputBuffer MASM - PullRequest
0 голосов
/ 07 июня 2019

Я написал программу, которая обрабатывает массив, и мне нужно проверить правильность ввода.Если вы вводите вместе с цифрами и буквами, то команда ввода зацикливается и не позволяет вводить данные, я решил сделать очистку буфера перед каждым вводом, но проблема осталась

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 Ответ

1 голос
/ 08 июня 2019

scanf[_s] чтение данных во внутренний буфер crt. звонок FlushConsoleInputBuffer не влияет на это. вместо этого нам нужно вызвать 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
...