|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Aug 2000
Messaggi: 608
|
Controllo input in C/C++: alcune domande.
Ciao a tutti, avrei bisogno di qualche delucidazione sulla gestione dell'input da tastiera in C/C++.
Di seguito è il classico giochino "indovina il numero", sulla base del quale avrei alcune domande da farvi per gestire le immissioni da tastiera da parte dell'utente: Codice:
#include <cstdlib> #include <iostream> #include <ctime> using namespace std; unsigned int insNumero(); void gioco(); int main() { char again; do { gioco(); do{ printf("\n\nVuoi giocare ancora? [s/n] "); again=getchar(); fflush(stdin); if (again!='s' && again!='n') printf("\nScelta non consentita. Premi 's' o 'n'"); } while (again!='s' && again!='n'); } while (again=='s'); return 0; } unsigned int insNumero() { int numInserito; do{ printf("\nInserisci il numero: "); scanf("%u", &numInserito); if (numInserito==0 || numInserito > 100) printf("\nDevi inserire un numero da 1 a 100!!!\n"); fflush(stdin); } while(numInserito==0 || numInserito > 100); return numInserito; } void gioco() { unsigned int numMagico; unsigned int numIndovina; srand(time(NULL)); numMagico=(rand()%100)+1; printf("\n\nIndovina il numero magico da 1 a 100\n"); do { numIndovina=insNumero(); if (numIndovina < numMagico) printf("\nHai inserito un numero troppo basso.\n"); else if (numIndovina > numMagico) printf("\nHai inserito un numero troppo alto.\n"); else { printf("COMPLIMENTI!!!\n"); printf("Il numero magico era proprio: %u", numMagico); } } while (numIndovina != numMagico); return; } Domanda 2: per evitare i soliti problemi con i caratteri rimanenti nel buffer di immissione, dopo ogni inserimento da parte dell'utente ho usato fflush(stdin) per svuotare il buffer ed evitare che all'immisione successiva venissero presi eventuali caratteri residui. Questo è un sistema corretto? Oppure esiste un sistema migliore per controllare l'eccedenza del buffer di stdin? Inoltre la funzione fflush(stdin) l'ho trovata cercando nei forum....ma possibile che nessun manuale di C/C++, fra le decine che possiedo, si degni di spiegare queste cose? Eppure il problema della ingestibilità del buffer di input è un problema molto diffuso, a quanto leggo in giro.... Domanda 3: per ora il programma è scritto in C, usando le funzioni standard printf e scanf. Ma se io avessi voluto rimanere sul C++ e usare cin per le immissioni dell'utente, in che modo si utilizza esattamente? So che la forma generale con l'operatore estrattore è "cin >> variabile", ma in che modo posso formattare l'input (come ad esempio"%u" in scanf) per essere sicuro che mi restituisca un valore e non un carattere? Grazie per la pazienza. ![]()
__________________
Intel Core2Quad Q6600 2,4GHz @ 3,0 GHz 2 Gb RAM 667 MHz ATI HD2900XT |
![]() |
![]() |
![]() |
#2 | |||
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Quote:
Ci sono altri modi per eliminare i caratteri in più: - Fare un ciclo while(getchar() != '\n'); - Evitare scanf ![]() Quote:
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|||
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Oct 2006
Città: milano
Messaggi: 1439
|
in effetti iostream e namespace std li potrebbe anche togliere no?
|
![]() |
![]() |
![]() |
#4 | |||
Senior Member
Iscritto dal: Aug 2000
Messaggi: 608
|
Quote:
Ma getch() e sua sorella getche() servono per leggere caratteri da stdin senza buffer, giusto? Come posso usarlo per verificare se l'utente digita dei caratteri invece che dei numeri? E poi mi sembra che getch() restituisca un tipo char, come lo uso per inserire valori in variabili int? ![]() Quote:
![]() Da quello che ho letto fgets e sscanf servono per le stringhe....dovrei usare quelli per ricevere numeri dal stdin? Ma poi hanno comunque il problema del buffer, giusto? Quindi dovrei in ogni caso svuotarlo, vero? ![]() Quote:
![]()
__________________
Intel Core2Quad Q6600 2,4GHz @ 3,0 GHz 2 Gb RAM 667 MHz ATI HD2900XT |
|||
![]() |
![]() |
![]() |
#5 | |||
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Quote:
Codice:
#include <iostream> using namespace std; /* ... */ int n; cin >> n if ( cin.fail() ) // ho inserito dei caratteri { cin.clear(); while( !isdigit( cin.peek() ) ) cin.ignore(); } Se preferisci che venga ignorata tutta la riga, allora puoi fare nel modo seguente Codice:
#include <iostream> using namespace std; /* ... */ int n; cin >> n if ( cin.fail() ) // ho inserito dei caratteri { cin.clear(); while( cin.peek() != '\n' ) cin.ignore(); } Quote:
Quote:
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele Ultima modifica di marco.r : 03-06-2007 alle 15:06. Motivo: tag sbagliati... |
|||
![]() |
![]() |
![]() |
#6 | ||
Senior Member
Iscritto dal: Aug 2000
Messaggi: 608
|
Quote:
![]() E' esattamente quello che cercavo. Sapevo che cin adatta l'input alla variabile che lo deve contenere, ma non conoscevo tutte le sottofunzioni peek, fail, clear e ignore. A dire il vero avevo visto queste cose qui: http://www.cplusplus.com/reference/iostream/istream/ ma non ci ho capito un gran ché, forse perchè sono agli inizi! ![]() Quote:
Comunque ora che mi hai dato la soluzione migliore la sostituisco senza dubbio. Grazie di tutto. ![]()
__________________
Intel Core2Quad Q6600 2,4GHz @ 3,0 GHz 2 Gb RAM 667 MHz ATI HD2900XT |
||
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Aug 2000
Messaggi: 608
|
Quote:
Codice:
while (getchar()!='\n') Prendi questo codice: Codice:
#include <iostream> using namespace std; int main() { int x; cout << "Inserisci un numero: "; cin >> x; if (cin.fail()) cout << "\nErrore"; else cout << "\nHai digitato: " << x; while (cin.get()!='\n'); cin.get(); return 0; } Ma se io, invece, inserisco uno o più caratteri, il programma stampa correttamente il messaggio "Errore" (sfruttando la funzione cin.fail() ), però poi si pianta nel ciclo while di svuotamento. Da quello che ho capito dal comportamento, in caso di errore nello stream di input non esiste più '\n' e il ciclo while diventa infinito! ![]() Quindi come risolvo? Cosa devo cercare invece di '\n'? ![]()
__________________
Intel Core2Quad Q6600 2,4GHz @ 3,0 GHz 2 Gb RAM 667 MHz ATI HD2900XT |
|
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Quote:
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
|
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Aug 2000
Messaggi: 608
|
Quote:
![]() Infatti adesso funziona, e in questo modo sono riuscito anche a trasformare il giochino del numero in modo da usare soltanto istruzioni C++ e abbandonare quelle standard del C. Grazie infinite! ![]() ![]()
__________________
Intel Core2Quad Q6600 2,4GHz @ 3,0 GHz 2 Gb RAM 667 MHz ATI HD2900XT |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 07:09.