Newsgroup: it.comp.lang.c
Titolo: getch() e scanf()

Semplice problema: 
1)leggo un carattere per volta con getch() per navigare in un menu 
2)quando vengono selezionate certe voci del menu, devo fare una
lettura dalla tastiera ... ed uso scanf()
Tuttavia quando la scanf()  prende il controllo, appare l'ultimo
carattere letto dalla getch().
A questo punto devo premere backspace per cancellarlo, altrimenti la
scanf() lo rilegge nuovamente.
Come si puo' evitare ?
[Borland C]

 wrote in message
news:3d04c83...@news.tiscalinet.it...

dopo la getch() prova a chiamare la fflush che pulisce lo stdin
...
var = getch();
fflush();
...

...
Cosi' svuoti tutti i buffer di output, non quelli di input (almeno, e'
undefined behaviour). Per svuotare lo stream di input devi:
1) usare una funzione specifica, che potresti trovare in qualche
libreria per la gestione del terminale
2) fare un ciclo di lettura su stdin fino alla prima newline (getchar,
getch, scanf.... vanno tutte bene a condizione che peschino dal buffer
della tastiera).
-- 
Mox
"Trust the programmer."
"Don't prevent the programmer from doing what needs to be done."
"Keep the language small and simple."
"Provide only one way to do an operation."

 della tastiera).
giusto
scusa ma mi ero confuso
l'inesperienza... :'(

 ha scritto nel messaggio
news:D46N8.116366$g04....@tornado.fastwebnet.it...


scusate, ma io faccio sempre "fflush(stdin);" e funziona!
"Undefined behaviour" vuol dire che pu accadere qualsiasi cosa, quello
che vuoi tu, niente, l'esatto contrario di quello che vuoi o anche
formattarti l'hard disk.
-- 
Marco Barisione (ICQ 84277092)

scusate, ma io faccio sempre "fflush(stdin);" e funziona!
Bene bene, ora ti spiego perche', ma solo se impari a quotare :)
fflush() e' una funzione prevista dallo standard ANSI C.
Lo standard dice in sintesi: fflush la usi per "svuotare" i buffer
associati agli stream di output (il che include anche quelli di
errore); se la chiami senza parametri ti svuota *tutti* i buffer
associati agli stream di output che sono aperti (dal programma).
Su stdin e in generale tutti i buffer associati agli stream di input
lo standard ti dice "undefined behaviour": quando lo standard dice
cosi' significa che imporre un comportamento potrebbe non essere
conveniente in certi casi, percio' lascia la massima liberta' di
azione.
In casi del genere e' possibile che:
- funzioni lo stesso, come nei casi in cui e' definito (nel tuo caso:
che svuoti perfettamente il buffer associato a stdin)
- funzioni in modo simile
- non faccia nulla
- scriva nel primo settore, primo cilintro, prima traccia del tuo
primo hd il nome della fidanzata/moglie del tuo vicino di casa
- evochi Lord Arioch (il protettore di Elric di Melnibone)
Entrambi questi comportamenti sono ammissibili, se escludi la
difficolta' di evocare Arioch senza un ingente sacrificio e un potente
sacerdote del Chaos, soprattutto in questo piano del multiverso. E lo
standard dicendoti "undefined behaviour" ti vuole dire che sono
possibili E perfettamente leciti a norma di standard.
Nel caso specifico di fflush(stdin) ti posso dire per sperimentazioni
personali che funziona sotto windows e sotto SunOS, mentre non
funziona sotto linux.
Questo ti insegna anche che i test empirici non funzionano in materia
di standard, proprio perche' esistono questi aspetti (una cosa simile
ti potrebbe capitare cercando di sovrascrivere un/una literal string).



Prima di tutto ti ringrazio per l'aiuto.
Scrivo alcune semplici righe per metere qualche punto fermo:
void main() {
   char Ch,Str[50];
   printf("\nPremi un tasto...");
   Ch=getch();
   printf("\nInserisci una stringa:");
   scanf("%s",Str);
   printf("Hai premuto il tast %c ed inserito la strina %s",Ch,Str);
   }
E qui' come dicevo e' tutto ok, tranne per il fato che non appena
prende il controllo la scanf ... riesce fuori il carattere letto da
getch.
Riscrivendelo nel modo seguente:
void main() {
   char Ch,Str[50];
   printf("\nPremi un tasto...");
   Ch=getch();
   while(getchar()!='\n');
   printf("\nInserisci una stringa:");
   scanf("%s",Str);
   printf("Hai premuto il tasto %c ed inserito la strina %s",Ch,Str);
   }
Ecco cosa succede:
Quando prende il controllo la getchar riappare sul monitor il
carattere letto da getch (proprio come succede con scanf) ed il
programma rimane impallato sulla getchar fino a che non premo enter.
Dopo aver premuto enter il ciclo viene ripetuto un numero di volte
pari ai caratteri inseiti prima dell'enter ... scaricandi il buffer.
E dopo continua regolarmente...
Ho dato un'occhiata alla getch sotto linux: e' una cosa completamente
differente da quella implementata in ambiente Borland e quindi non e'
un confronto utile (al momento sto sviluppando in ambiente Borland C++
5.5 per Win32).
Un altroconfronto l'ho fatto con Borland Turbo C++ 3.0 : funziona
perfettamente senza il ciclo while ed il carattere letto con getch non
si ripresenta...
...credo proprio che il mio problema non abbia soluzione, od almeno
non una soluzione standard
Praticamente

formattarti l'hard disk.
L'ultima sembra simpatica!
NM

 ha scritto nel messaggio
news:iv5agu49jhvj4fmp4...@4ax.com...



..e poi c'era la marmotta che confezionava la cioccolata.
Se era cosi` tanto utile e "vicino a noi umani", com'e` che quegli alieni che
hanno definito l'ANSI C non c'hanno pensato e hanno detto "massi`, via,
facciamolo comportare cosi`" al posto di lasciarlo "non definito" ?
Sono macchine?
Sono alieni?
Non c'avevano tempo?
Mirano alla conquista del mondo e alla pazzia di tutti i programmatori?
Mah, ai posteri l'ardua sentenza...
Adieu,
-- 
Lestat de Lioncourt                               |          Ciro Mattia Gonano
  JabberID: 
les...@jabber.students.cs.unibo.it
    |    Undergraduate Student in
  ICQ#: 52631406                                  |         Computer Science at
  URL: 
http://www.CS.UniBO.It/~gonano
             |       University of Bologna
            <powered by Linux Slackware 8.1 on Kernel 2.4.18-xfs>

che Linux sarà un po' più vicina a noi umani. Ecco il successo di MS!
Quando lo standard dice "undefined behaviour" e' perche' su alcuni
sistemi implementare una data feature puo' essere troppo oneroso (es
imporre che il char sia signed o unsigned) o addirittura impossibile
una data scelta.
Nel caso di fflush(stdin), stdin potrebbe essere una macro, o un file
speciale... la spiegazione piu' plausibile e' in linux entriamo in
questi casi, sotto Win no (evidentemente che se stdin e' un file
normale e' molto comodo implementarci su la fflush).
Le libc sono un po' un accozzaglia di materiale perche' sono state
sviluppate da tante persone in tanti anni, questo si... pero' se non
implementano qualcosa difficilmente e' una dimenticanza, ma ci sono
motivi ben precisi.


 motivi ben precisi.
OK! Questo è un KO alla mia tesi (suppenendo che ci siano i motivi ben
precisi: questo è un ottimo argomento di ricerca. Ma io ci credo, perchè
sarebbe stupido altrimenti.)
COMMENTO: le tue risposte sono molto professionali: complimenti.
Ciao,
jhonpp.
P.S. Spero di aver capito il "quoting".
Per quanto riguarda la differenza tra R e Re ho ancora difficoltà!


Io uso Outlook Express e quando utilizzo il comando "rispondi al newsgroup"
mi mette la "R:". Ho capito che dovrei correggerla io a mano, ma perchè? Che
cos'è l'RFC? Qual è l'utilità di questa regola?
johnpp

cos'è l'RFC? Qual è l'utilità di questa regola?
Oki il quoting, ora ti spiego il reply.
RFC sta' per Request For Comment, sono dei documenti diciamo pubblici
che una volta approvati (in modi e tempi che non ci interessano)
diventano lo standard di fatto per le applicazioni. Tutti si attengono
alla RFC in materia di XXX per avere tutti la stessa base comune.
L'RFC della mail e delle News specificano che i reply devono essere
fatti mettendo i caratteri "Re:" davandi al subject del messaggio per
specificare che la risposta fa' parte dello stesso thread. I news
reader piu' evoluti non si appoggiano solo a questo, ma anche ad altre
info, come per es. il campo References.
Ora, la MS se ne e' sempre fregata e permette i reply usando la
sintessi "R:", scombinando di fatto i news/mail reader aderenti allo
standard (quindi alla RFC). Alcuni client piu' evoluti ancora possono
considerare il "R:" (sbagliato) come un "Re:" e non scombinare la
corretta visualizzazione in thread.
Esistono delle patch per Outlook Express per correggere questo
problema, ma ora come ora non saprei indicarti dove.


Per quanto riguarda la differenza tra R e Re ho ancora difficoltà!
http://www.vene.ws/mail/r-out.asp



ho seguito il consiglio di attivare l'opzione "In risposta al messaggio
utilizza sempre intestazioni in inglese" -> Funziona!!
Grazie ragazzi!

 L'ultima sembra simpatica!
Ma non impossibile.
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG