Torna indietro   Hardware Upgrade Forum > Software > Programmazione

ASUS NUC 15 Pro e NUC 15 Pro+, mini PC che fondono completezza e duttilità
ASUS NUC 15 Pro e NUC 15 Pro+, mini PC che fondono completezza e duttilità
NUC 15 Pro e NUC 15 Pro+ sono i due nuovi mini-PC di casa ASUS pensati per uffici e piccole medie imprese. Compatti, potenti e pieni di porte per la massima flessibilità, le due proposte rispondono in pieno alle esigenze attuali e future grazie a una CPU con grafica integrata, accompagnata da una NPU per la gestione di alcuni compiti AI in locale.
Cybersecurity: email, utenti e agenti IA, la nuova visione di Proofpoint
Cybersecurity: email, utenti e agenti IA, la nuova visione di Proofpoint
Dal palco di Proofpoint Protect 2025 emerge la strategia per estendere la protezione dagli utenti agli agenti IA con il lancio di Satori Agents, nuove soluzioni di governance dei dati e partnership rafforzate che ridisegnano il panorama della cybersecurity
Hisense A85N: il ritorno all’OLED è convincente e alla portata di tutti
Hisense A85N: il ritorno all’OLED è convincente e alla portata di tutti
Dopo alcuni anni di assenza dai cataloghi dei suoi televisori, Hisense riporta sul mercato una proposta OLED che punta tutto sul rapporto qualità prezzo. Hisense 55A85N è un televisore completo e versatile che riesce a convincere anche senza raggiungere le vette di televisori di altra fascia (e altro prezzo)
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 01-10-2009, 08:19   #1
zanardi84
Senior Member
 
L'Avatar di zanardi84
 
Iscritto dal: Apr 2004
Città: La regione del Triplete
Messaggi: 5744
[C/C++] Controllo input tastiera

Salve,
Sono alle prese con una funzione per la creazione di un semplice menu.

Il programma esegue determinate azioni in base alla voce di menu che inserisco.

Gestisco il tutto con uno switch.

Codice:
void scelta()
{
   int scelta;
while ( ( scelta = getchar() ) != EOF ) {
      
     
      switch ( scelta ) { 

         case 'S': 
         case 's': 
            cout<<"messaggio1"<<endl; 
            break; 
            
         case 'D': 
         case 'd':
            cout<<"messaggio2"<<endl; 
            break; 
         case 'M': 
         case 'm':
           cout<<"messaggio3"<<endl; 
            break;

       
         default: 
           cout<<"Scelta non corretta. Ridigitare."<<endl; 
                        break;
      } /* fine switch */
   
   } /* fine while */
} /* fine funzione */
Funziona, nel senso che se immetto un carattere che non c'entra mi segnala subito l'errore. se digito per esempio S o s mi stampa il messaggio.

Se invece digito SS, cioè 2 volte S mi stampa 2 volte il messaggio. Se digito SD mi stampa i 2 messaggi corrispondenti.

Vorrei, nel modo più semplice possibile (con una funzione che posso richiamare) fare il controllo in modo che se digito 2 caratteri invece di uno mi segnala l'errore.

Qualche idea?
__________________
Trattative felicemente concluse con domienico120, xbax88 ed engiel, ottimi e seri utenti.
zanardi84 è offline   Rispondi citando il messaggio o parte di esso
Old 02-10-2009, 10:04   #2
zanardi84
Senior Member
 
L'Avatar di zanardi84
 
Iscritto dal: Apr 2004
Città: La regione del Triplete
Messaggi: 5744
Ho modificato la funzione eliminando le lettere, sostituendole con dei comodi numeri
Adesso risolve correttamente lo switch, mentre non esce dal while.

Codice:
using namespace std;
void scelta();
int main(int argc, char *argv[])
{
    scelta();
    system("PAUSE");
    return EXIT_SUCCESS;
}

void scelta()
{
   int scelta;
   cout<< "Digitare 1 ...."<<endl;
   cout<< "Digitare 2 ....."<<endl;
   cout<< "Digitare 3 ......."<<endl;
   cout<< "Digitare 0 per uscire"<<endl;

   cin>>scelta;

   /* ripete finchè non si immette 0*/
   while ( scelta !=0 ) {
   
      /* azione in base all'input */
      switch ( scelta ) { 

         case 1:
            cout<<"mess1"<<endl;
            
            break; /*esce dallo switch */
            
         case 2:
            cout<<"mess2"<<endl; 
           
            break; /* esce dallo switch */

         case 3: 
           cout<<"mess3"<<endl; 
          
           break; /* esce dallo switch */

         case '\n': /* ignora gli a capo, */
         case '\t': /* tabs, */
         case ' ':  /* spazi in input */
          break; /* esce dallo switch */

         default: /* tutti gli altri caratteri */
           cout<<"Scelta non corretta. Ridigitare."<<endl; 
          
           break;
      } /* fine switch */
   
   } /* fine while */
} /* fine funzione */
Pensavo a sta cosa: il while viene chiuso solo se la variabile va a 0. Quindi se nei case poi setto la variabile scelta a 0, il while si trova il nuovo valore a 0 ed esce. Quindi lo fa comunque 2 volte il ciclo.
Se invece è 0 il valore, esce direttamente.
Se il valore non è uno di quelli previsti al momento va in loop. Pensavo quindi: se oltre alla variabile io ne aggiungessi una di status (rendendo quindi la funzione int e non void) che mi viene restituita al main, il quale mi opera un controllo, se status è 0 vuol dire che la funzione è andata bene e ha preso il valore che gli occorreva, se invece è -1 per esempio vuol dire che la funzione ha preso un valore che non andava e deve ricominciare.

Che ne dite come soluzione? Non ci sarebbe alternativamente un modo per evitare di ripartire con la funzione? Per esempio: inserisco il valore che non va bene, lo switch viene risolto, ma il valore è sempre diverso da 0, esce dal while e lo reinizia?
__________________
Trattative felicemente concluse con domienico120, xbax88 ed engiel, ottimi e seri utenti.
zanardi84 è offline   Rispondi citando il messaggio o parte di esso
Old 02-10-2009, 19:09   #3
Jecko
Senior Member
 
L'Avatar di Jecko
 
Iscritto dal: Nov 2003
Città: Il Poli
Messaggi: 992
personalmente avrei tenuto la prima soluzione per il menù. semplicemente inserisci questa riga dopo lo switch
while(getchar()!="\n");
con questa però mangi tutto l'input che non è stato consumato sia esso corretto o meno. Per segnalare l'errore a quel punto devi aggiustarti con un flag.
__________________
VENDO: PC Desktop Gaming AMD
Trattative su hwup: 20 trattative
Jecko è offline   Rispondi citando il messaggio o parte di esso
Old 06-10-2009, 07:41   #4
zanardi84
Senior Member
 
L'Avatar di zanardi84
 
Iscritto dal: Apr 2004
Città: La regione del Triplete
Messaggi: 5744
Ho rimodificato il programma tornando alla versione iniziale. Ho aggiunto un getchar() che mi evita i loops e ho trasformato ogni digitazione in maiuscolo.

Codice:
void scelta()
{
   int scelta;
while ( ( scelta = getchar() ) != EOF ) {
  getchar();
   scelta=toupper(scelta);    
     
      switch ( scelta ) { 

       
         case 'S': 
            cout<<"messaggio1"<<endl; 
            break; 
            
        
         case 'D':
            cout<<"messaggio2"<<endl; 
            break; 
          
         case 'M':
           cout<<"messaggio3"<<endl; 
            break;

       
         default: 
           cout<<"Scelta non corretta. Ridigitare."<<endl; 
                        break;
      } /* fine switch */
   
   } /* fine while */
} /* fine funzione */
Rimane un problema che non so come risolvere: se inserisco per esempio MM o SD o S e un altro carattere mi stampa:

SS -> messaggio1 messaggio1
SD -> messaggio1 messaggio2
MM -> messaggio3 messaggio3
SG -> messaggio1 e va a capo in attesa di digitazione (non stampa il messaggio del default ma presenta subito il cursore per una ridigitazione).

Qualche idea?
__________________
Trattative felicemente concluse con domienico120, xbax88 ed engiel, ottimi e seri utenti.
zanardi84 è offline   Rispondi citando il messaggio o parte di esso
Old 06-10-2009, 09:01   #5
rnuzzo
Senior Member
 
L'Avatar di rnuzzo
 
Iscritto dal: Nov 2005
Città: Cavallino (LE)
Messaggi: 335
Pe la variabile scelta dichiara cosi: char scelta = [1];Non so prova e fammi sapere
__________________
Notebook: HP DV6-6159sl -- PC CPU Intel i7 3770k, MB MSI Z77a-g45, RAM Corsair XMS 3 low profile 1600, SV Gigabyte HD6950, SSD Corsair GT60, HD WD 500Gb CG, WD750Gb CB, DVD-ROM LG lightscribe, ALI 750TX550W, CASE CM Advanced II, MONITOR Asus VW224T x 3, TASTIERA Thermaltake Challenger Pro, MOUSE Corsair M60, CUFFIE Roccat kave 5.1, SISTEMA AUDIO JBL ESC.XITE , MOUSEPAD Roccat Taito + CM Storm

Ho concluso positivamente con: berna29,spl,Alex_Lupin,rb1205,katoble
rnuzzo è offline   Rispondi citando il messaggio o parte di esso
Old 06-10-2009, 09:17   #6
zanardi84
Senior Member
 
L'Avatar di zanardi84
 
Iscritto dal: Apr 2004
Città: La regione del Triplete
Messaggi: 5744
Levando il secondo getchar() non ci sono problemi a quanto pare, non va in loop. Continua però a dare problemi.

Dichiarando la variabile come char scelta = [1]; ottengo errori.
__________________
Trattative felicemente concluse con domienico120, xbax88 ed engiel, ottimi e seri utenti.
zanardi84 è offline   Rispondi citando il messaggio o parte di esso
Old 06-10-2009, 09:33   #7
rnuzzo
Senior Member
 
L'Avatar di rnuzzo
 
Iscritto dal: Nov 2005
Città: Cavallino (LE)
Messaggi: 335
Specifica gli errori per favore.
__________________
Notebook: HP DV6-6159sl -- PC CPU Intel i7 3770k, MB MSI Z77a-g45, RAM Corsair XMS 3 low profile 1600, SV Gigabyte HD6950, SSD Corsair GT60, HD WD 500Gb CG, WD750Gb CB, DVD-ROM LG lightscribe, ALI 750TX550W, CASE CM Advanced II, MONITOR Asus VW224T x 3, TASTIERA Thermaltake Challenger Pro, MOUSE Corsair M60, CUFFIE Roccat kave 5.1, SISTEMA AUDIO JBL ESC.XITE , MOUSEPAD Roccat Taito + CM Storm

Ho concluso positivamente con: berna29,spl,Alex_Lupin,rb1205,katoble
rnuzzo è offline   Rispondi citando il messaggio o parte di esso
Old 06-10-2009, 09:41   #8
zanardi84
Senior Member
 
L'Avatar di zanardi84
 
Iscritto dal: Apr 2004
Città: La regione del Triplete
Messaggi: 5744
Quote:
Originariamente inviato da rnuzzo Guarda i messaggi
Specifica gli errori per favore.
Ero di fretta e non ho implementato correttamente

Adesso, dichiarando come mi hai detto ottengo: initializer fails to determinate size of scelta.

Se invece metto char scelta[1]; e lavoro sulla singola casella accedendo così

Codice:
while ( ( scelta[0] = getchar() ) != EOF ) {
   
   scelta[0]=toupper(scelta[0]); /* rende maiuscolo il carattere inserito. Includere a inizio programma ctype.h */
      /* azione in base all'input */
      switch ( scelta[0] ) { 
......
è uguale a prima.

Adesso stavo pensando a sta cosa: e se usassi isalpha() della libreria ctype?
Magari si semplifica un attimo. Devo capire prima cosa fa di preciso e cosa prende.
__________________
Trattative felicemente concluse con domienico120, xbax88 ed engiel, ottimi e seri utenti.
zanardi84 è offline   Rispondi citando il messaggio o parte di esso
Old 06-10-2009, 11:56   #9
rnuzzo
Senior Member
 
L'Avatar di rnuzzo
 
Iscritto dal: Nov 2005
Città: Cavallino (LE)
Messaggi: 335
Io sono niubbo totale e su questo

Quote:
Adesso stavo pensando a sta cosa: e se usassi isalpha() della libreria ctype?
non saprei come aiutarti.

Ma perche non usi dei semplici 'if'?Cosi risolvi tutto

Ma studi su un Deitel?
__________________
Notebook: HP DV6-6159sl -- PC CPU Intel i7 3770k, MB MSI Z77a-g45, RAM Corsair XMS 3 low profile 1600, SV Gigabyte HD6950, SSD Corsair GT60, HD WD 500Gb CG, WD750Gb CB, DVD-ROM LG lightscribe, ALI 750TX550W, CASE CM Advanced II, MONITOR Asus VW224T x 3, TASTIERA Thermaltake Challenger Pro, MOUSE Corsair M60, CUFFIE Roccat kave 5.1, SISTEMA AUDIO JBL ESC.XITE , MOUSEPAD Roccat Taito + CM Storm

Ho concluso positivamente con: berna29,spl,Alex_Lupin,rb1205,katoble
rnuzzo è offline   Rispondi citando il messaggio o parte di esso
Old 06-10-2009, 12:57   #10
zanardi84
Senior Member
 
L'Avatar di zanardi84
 
Iscritto dal: Apr 2004
Città: La regione del Triplete
Messaggi: 5744
Quote:
Originariamente inviato da rnuzzo Guarda i messaggi
Io sono niubbo totale e su questo



non saprei come aiutarti.

Ma perche non usi dei semplici 'if'?Cosi risolvi tutto

Ma studi su un Deitel?
Sì, su un Deitel
__________________
Trattative felicemente concluse con domienico120, xbax88 ed engiel, ottimi e seri utenti.
zanardi84 è offline   Rispondi citando il messaggio o parte di esso
Old 06-10-2009, 14:02   #11
rnuzzo
Senior Member
 
L'Avatar di rnuzzo
 
Iscritto dal: Nov 2005
Città: Cavallino (LE)
Messaggi: 335
Che capitolo?
__________________
Notebook: HP DV6-6159sl -- PC CPU Intel i7 3770k, MB MSI Z77a-g45, RAM Corsair XMS 3 low profile 1600, SV Gigabyte HD6950, SSD Corsair GT60, HD WD 500Gb CG, WD750Gb CB, DVD-ROM LG lightscribe, ALI 750TX550W, CASE CM Advanced II, MONITOR Asus VW224T x 3, TASTIERA Thermaltake Challenger Pro, MOUSE Corsair M60, CUFFIE Roccat kave 5.1, SISTEMA AUDIO JBL ESC.XITE , MOUSEPAD Roccat Taito + CM Storm

Ho concluso positivamente con: berna29,spl,Alex_Lupin,rb1205,katoble
rnuzzo è offline   Rispondi citando il messaggio o parte di esso
Old 06-10-2009, 23:02   #12
Ibrahimovic
Member
 
Iscritto dal: Jan 2007
Città: Asti
Messaggi: 256
Quote:
Originariamente inviato da zanardi84 Guarda i messaggi
Ho rimodificato il programma tornando alla versione iniziale. Ho aggiunto un getchar() che mi evita i loops e ho trasformato ogni digitazione in maiuscolo.

Codice:
void scelta()
{
   int scelta;
while ( ( scelta = getchar() ) != EOF ) {
  getchar();
   scelta=toupper(scelta);    
     
      switch ( scelta ) { 

       
         case 'S': 
            cout<<"messaggio1"<<endl; 
            break; 
            
        
         case 'D':
            cout<<"messaggio2"<<endl; 
            break; 
          
         case 'M':
           cout<<"messaggio3"<<endl; 
            break;

       
         default: 
           cout<<"Scelta non corretta. Ridigitare."<<endl; 
                        break;
      } /* fine switch */
   
   } /* fine while */
} /* fine funzione */
Rimane un problema che non so come risolvere: se inserisco per esempio MM o SD o S e un altro carattere mi stampa:

SS -> messaggio1 messaggio1
SD -> messaggio1 messaggio2
MM -> messaggio3 messaggio3
SG -> messaggio1 e va a capo in attesa di digitazione (non stampa il messaggio del default ma presenta subito il cursore per una ridigitazione).

Qualche idea?
Guarda, è ovvio che reagisce così il tuo programma!!!

La variabile scelta è una variabile char, contiene UN solo carattere alla volta, se tu inserisci due lettere (poniamo S e G ) la getchar attribuirà a scelta prima la S, il tuo switch selezionerà l'operazione, poi il ciclo ricomincera' e la getchar consumerà ancora il buffer attribuendo a scelta la G e eseguendo l'operazione di G.

E' ovvio proprio per struttura del programma, non puoi evitarlo.

Volendo, potresti dichiarare scelta come vettore di caratteri, e printare errore nel caso in cui ci siano piu' di una lettera/operatore e il NULL nella stringa...

Del tipo
if ( strlen( scelta ) > 1 )
printf(" Errore nell'imput bla bla bla \n");



EDIT:

Se proprio vuoi, puoi fare così.
Poniamo che tu la prima lettera che inserisci è sempre la lettera che volevi inserire, e che se ne inserisci due vuoi segnalato l'errore, perchè inserita piu' di una lettera.. ok?

Bene, in un esempio si potrebbe dire che con un imput come questo Snjknsvjhbsdgv noi volevamo intendere "Esegui l'istruzione 'S' " e che dopo la s ci siamo sbagliato e abbiamo digitato qualcosa in piu...

Be, puoi dichiarare scelta come vettore di caratteri, leggere l'imput e usare lo switch infine su scelta[0], ossia sul primo elemento della stringa scelta.

Se vuoi conservare il maiuscolo chiamala in questo modo : switch( toupper( scelta[0] ) ).

Così facendo se la stringa fosse ghbhcd andrai a selezionare l'operazione G dello switch
__________________

Ho concluso affari con: Samurri, kosimiro, mAiDeN75, Raziel1984, deidara, billy99. gertuzz

Ultima modifica di Ibrahimovic : 06-10-2009 alle 23:09.
Ibrahimovic è offline   Rispondi citando il messaggio o parte di esso
Old 06-10-2009, 23:59   #13
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2775
Ma hai provato la soluzione che ti ha proposto Jecko? Mi sembrava corretta...
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 07-10-2009, 07:58   #14
zanardi84
Senior Member
 
L'Avatar di zanardi84
 
Iscritto dal: Apr 2004
Città: La regione del Triplete
Messaggi: 5744
Dunque, ho notato che la mia funzione è lunghetta, fa più di una cosa ed è troppo specifica. Ho pertanto deciso di crearne una generale che posso chiamare quando mi fa comodo e che fa solo ed esclusivamente il controllo dell'input.

Ibra, secondo te cosa è più elegante? Segnalare subito l'errore o prendere per buono solo il primo carattere della stringa?
__________________
Trattative felicemente concluse con domienico120, xbax88 ed engiel, ottimi e seri utenti.
zanardi84 è offline   Rispondi citando il messaggio o parte di esso
Old 24-10-2009, 09:58   #15
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Mi è arrivata una erronea segnalazione da qualcuno, in ogni caso rispondo...

char scelta = [1]; non esiste in C o C++

La variabile char deve essere inizializzata o con un intero o con un carattere fra apici singoli.

La risposta corretta era quella di Jecko, dopo la lettura del primo carattere all'interno della condizione del while, bisogna svuotare il buffer di input:

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

Questo lo puoi mettere subito dopo l'apertura della parentisi del while.
Una soluzione molto più C++ sarebbe stata questa:
Codice:
while((scelta = cin.get()) != 0) {
  string temp;
  getline(cin, temp);
cionci è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


ASUS NUC 15 Pro e NUC 15 Pro+, mini PC che fondono completezza e duttilità ASUS NUC 15 Pro e NUC 15 Pro+, mini PC che fondo...
Cybersecurity: email, utenti e agenti IA, la nuova visione di Proofpoint Cybersecurity: email, utenti e agenti IA, la nuo...
Hisense A85N: il ritorno all’OLED è convincente e alla portata di tutti Hisense A85N: il ritorno all’OLED è convi...
Recensione Borderlands 4, tra divertimento e problemi tecnici Recensione Borderlands 4, tra divertimento e pro...
TCL NXTPAPER 60 Ultra: lo smartphone che trasforma la lettura da digitale a naturale TCL NXTPAPER 60 Ultra: lo smartphone che trasfor...
Steelseries Arctis Nova Elite: le prime ...
30 anni di PlayStation da indossare: arr...
Amazon lancia gli Echo più potent...
Amazon rinnova la gamma Fire TV: ecco le...
Ring lancia le sue prime videocamere con...
Blink amplia la gamma di videocamere di ...
Jaguar Land Rover riprende (gradualmente...
HONOR inaugura il primo ALPHA Flagship S...
Yamaha: ecco il brevetto del 'finto moto...
'Console obsoleta e utenti ingannati': u...
Stop al ransomware su Google Drive, graz...
L'IA è la nuova interfaccia utent...
Battlefield 6: confermata la dimensione ...
Windows 11 porta il Wi-Fi 7 alle aziende...
Logitech MX Master 4 subito disponibile ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 19:24.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v