PDA

View Full Version : Pulire il buffer di tastiera[c/c++]


alderighi
26-01-2004, 09:18
Cerco una funzione che pulisca il buffer di tastiera, perchè sto costruendo un gico in stile asteroids per una esercitazione di scuola, lavoriamo su uno schifosissimo borland 5.02 in modalita grafica sotto dos a 256 colori, e non riesco a pulire i tasti premuti precedentemente neanche con fflush(stdin);, qualcuno di voi massimi esperti conosce un qualsiasi modo per poter risolvere questo problema, anche includendo delle librerie o con un pezzo di codice scritto in assembler, come vi pare, basta funzioni.
La navicella si sposta però avvolta rimangono in memoria i tasti premuti precedentemente e va un po come gli pare.
Cionci aiutami!!!
Grazie

alderighi
27-01-2004, 14:11
up
nessuno che mi da una mano?

ilsensine
27-01-2004, 14:17
Un modo (non standard e poco pulito) è usare le funzioni di conio.h:
while(kbhit()) getch();

Gogeta ss4
02-02-2004, 21:35
fflush(stdin);

Ziosilvio
03-02-2004, 00:24
Originariamente inviato da Gogeta ss4
fflush(stdin);

E' una soluzione consigliata spesso.
Purtroppo non è standard, e può funzionare o meno a seconda del compilatore.
(E, a quanto ci dice alderighi, in questo caso non va.)

A proposito: catturare un segnale da tastiera (anziché leggere semplicemente un carattere dallo standard input) è un'operazione fortemente machine-dependent.
Temo che in questo caso sia d'obbligo consultare il manuale del compilatore.

AnonimoVeneziano
04-02-2004, 16:43
Raga , io ho trovato anke



while ( getchar() != '\n' );



e sembra funzionare , ank io avevo un problema con la funzione "scanf" (quando veniva inserito un carattere al posto di un intero la scanf "impazziva e andava in loop" ) , che ho risolto con questo codice qua sopra, ma per ste operazioni non c'è una procedura standard? Su linux ad esempio "fflush(stdin);" non va manco a pagarlo (dato che a quanto sembra fflush con stdin può dare risultati imprevisti) , cioè , io sul mio libro di C non ho trovato niente ,e non mi è sembrato di trovare niente neanke sul libro di quei ragazzacci di Kerningam e Ritchie , insomma , quand'è che questa operazione si rende necessaria generalmente , e qual'è la procedura migliore per farla? :D

Grazie

Ciao

ilsensine
04-02-2004, 16:56
Su linux ad esempio "fflush(stdin);" non va manco a pagarlo
#include <termios.h>

AnonimoVeneziano
04-02-2004, 17:13
:eek: :eek: :eek:


:D

Ma dici che è una soluzione consigliabile anke se non specificata dallo standard? :)

Ciao

EDIT : Comunque ilsensine , ho provato a fare come mi hai detto tu , ossia includere "termios.h" , e poi ho provato "fflush(stdin);" , al posto del codice che avevo postato poco sopra , ma non sembra funzionare , con questa va in LOOP e genera una roba del genere :

00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in instruction shell
00 ? Sorry , no letters in inst
bash-2.05b$



Mentre dovrebbe essere :

00 ? s
Sorry , no letters in instruction shell
00 ?


:(

ilsensine
04-02-2004, 17:47
Originariamente inviato da AnonimoVeneziano
Ma dici che è una soluzione consigliabile anke se non specificata dallo standard? :)
Certo che è standard (POSIX)


EDIT : Comunque ilsensine , ho provato a fare come mi hai detto tu , ossia includere "termios.h" , e poi ho provato "fflush(stdin);" , al posto del codice che avevo postato poco sopra , ma non sembra funzionare , con questa va in LOOP e genera una roba del genere :
Scordati fflush!
Dai una occhiata a man termios ;)

AnonimoVeneziano
04-02-2004, 18:06
Mi inginocchio al tuo cospetto , e ti chiedo umilmente di dirmi come esare le funzioni di sto header per flushare lo STDIN , perchè nella mia somma ignoranza non riesco a decifrare una pippa del man di "termios" :D :angel:

Ciao

AnonimoVeneziano
04-02-2004, 20:46
Nun me abbandonà ilsensì!! :D

Ciao

ilsensine
04-02-2004, 21:14
tcflush? ;)

AnonimoVeneziano
04-02-2004, 21:20
Originariamente inviato da ilsensine
tcflush? ;)


Si , l'avevo pensato ank io , ma il problema è come lo uso? :D

Cioè , io sono ankora un principiante , e del MAN non ci ho capito una mazza .

Ho solo capito che al secondo membro della funzione ci devo piazzare "TCIFLUSH" e quindi diventa :

tcflush(XXX, TCIFLUSH);

ma al primo membro che ci metto? :D

Ho provato

tcflush(stdin, TCIFLUSH);

Ma ovviamente non funziona :D e mi spara sto warning alla compilazione:

simpletron.c: In function `main':
simpletron.c:40: warning: passing arg 1 of `tcflush' makes integer from pointer without a cast


Come la devo configurare sta funz?

ilsensine
04-02-2004, 21:42
man fileno :mbe:

AnonimoVeneziano
04-02-2004, 21:56
Ho tentato sta forma , ma non sembra funzionare :

tcflush(fileno(stdin), TCIFLUSH);


Avrebbe dovuto funzionare o ho scannato anke in questo caso? :D

Ciao

ilsensine
04-02-2004, 22:02
Boh ho provato, e mi funziona...

AnonimoVeneziano
04-02-2004, 22:16
Originariamente inviato da ilsensine
Boh ho provato, e mi funziona...


A me no , ho provato anke con sto programmino di prova :


#include <stdio.h>
#include <termios.h>

int main()
{

int prova;

scanf("%d", &prova);
printf("%d\n", prova);
tcflush(fileno(stdin), TCIFLUSH);
scanf("%d", &prova);
printf("%d\n", prova);
return 0;
}


Ma il secondo scanf , se metto un carattere al posto di un intero al momento dell' immissione dell'input del primo scanf, è come se non esistesse , in pratica l'output che ottengo è questo :


bash-2.05b$ ./test <------ Parte il programma
a <------ Immetto un carattere al posto di un intero
1073821792 <------ Viene printato un valore intero dal primo printf
1073821792 <------ Il secondo scanf è come se non esistesse e viene subito printato il valore dal secondo printf
bash-2.05b$



Idee?

:cry:

Ciao

ilsensine
04-02-2004, 22:23
Originariamente inviato da AnonimoVeneziano
Idee?

Sì, ma ora devo staccare. Ne riparliamo domani.

(Indizio: stdin è line-buffered di default)

AnonimoVeneziano
04-02-2004, 22:25
Originariamente inviato da ilsensine
Sì, ma ora devo staccare. Ne riparliamo domani.

(Indizio: stdin è line-buffered di default)


Ok , ciao :)

ilsensine
05-02-2004, 09:25
#include <stdio.h>
#include <termios.h>

int main() {
int prova;
struct termios tios;
int fd = fileno(stdin);

tcgetattr(fd, &tios);
tios.c_lflag &= ~ICANON;
tios.c_cc[VMIN] = 1;
tios.c_cc[VTIME] = 0;
tcsetattr(fd, TCSAFLUSH, &tios);

scanf("%d", &prova);
printf("%d\n", prova);
tcflush(fd, TCIFLUSH);
scanf("%d", &prova);
printf("%d\n", prova);
return 0;
}

AnonimoVeneziano
05-02-2004, 14:33
bash-2.05b$ ./prova2
g134513996
134513996


Adesso non mi da neanke il tempo di schiacciare invio :(

Ciao

ilsensine
05-02-2004, 17:09
Sì perché la scanf esamina i dati "in tempo reale", in attesa di quello che cerca. Con la modifica che ho fatto, stdin "invia" i dati appena disponibili (normalmente aspetta una linea completa).
Cmq ho notato che neanche così si risolve completamente, credo che la scanf usi un suo buffer interno. Utilizzando la read, ad esempio, il programma mi ha funzionato come dovrebbe.

AnonimoVeneziano
05-02-2004, 17:23
Ok , grazie :)