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