Я пытаюсь узнать, как предотвратить отправку с клавиатуры нескольких символов на экран и в scanf
под DOS. Я использую Turbo-C со встроенной сборкой.
Если символы, введенные с клавиатуры:
ммммммммгггггг нннннаааааммммммеееее iiiiiissss HHHHaaaaiiiimmmm
Символы, видимые на консоли и обработанные scanf
, будут следующими:
меня зовут Хаим
Основной вывод исходит из кода на C, который мне не разрешено трогать. Я должен реализовать eliminate_multiple_press
и uneliminate_multiple_press
, не касаясь промежуточного кода.
Код Turbo-C, который я написал до сих пор:
#include <stdio.h>
#include <dos.h>
#include <string.h>
volatile char key;
volatile int i=0;
void interrupt (*Int9save) (void);
void interrupt kill_multiple_press()
{
asm{
MOV AL, 0
MOV AH,1
INT 16h
PUSHF
CALL DWORD PTR Int9save
MOV AX,0
}
asm{
JZ notSet
MOV key, AL
MOV AH, 04H
INT 16H
}
notSet:
//I am not sure what to do from here...............
I also know that it should be related to the zero flag, but what I
wrote so far didn`t effect on multiple characters.
}
void eliminate_multiple_press()
{
Int9save=getvect(9);
setvect(9,kill_multiple_press);
}
void uneliminate_multiple_press()
{
setvect(9,Int9save);
}
void main()
{
char str[10000]="";
clrscr();
eliminate_multiple_press();
printf("Enter your string: ");
scanf("%s",&str);
printf("\n%s",str);
uneliminate_multiple_press();
}
Полученная мной информация, относящаяся к решению, — это подпрограммы BIOS клавиатуры, которые можно найти по этой ссылке а>:
Проблемы, которые у меня возникают, вероятно, связаны с непониманием того, что делать на метке notSet
. Решение похоже связано с использованием буфера и регистра AX (особенно AL), но я действительно понятия не имею, как сделать scanf
, чтобы получить нужный мне результат. Есть ли у кого-нибудь идеи, как я могу завершить этот код для достижения желаемого эффекта?
16h
функция01h
— это вызов BIOS, который считывает состояние клавиатуры. Если клавиша была нажата, функция возвращает код сканирования и его символ ASCII вAH
иAL
, а флагZ
сбрасывается. Это более или менее эквивалентно функции MS Ckbhit()
, доступной вconio
. Однако он не читает клавиатуру, и статус сохраняется до тех пор, пока клавиша не будет прочитана прерыванием16h
функцией00h
, которая более или менее эквивалентна функции MS Cgetch()
. Это может объяснить, почему вы получаете несколько значений от того, что вы считаете одним нажатием клавиши. - person Weather Vane   schedule 18.08.201816h
04h
, что странно, поскольку Ральф Браун говорит, что она используется по-разному для установки нажатия клавиши или на Tandy 2000 для очистки буфера. Я не понимаю, почему это здесь, поскольку это не задокументировано в моей книге MSDOS. - person Weather Vane   schedule 18.08.2018