Visualizzazione dei risultati da 1 a 10 su 10

Discussione: [C++] User input check

  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    41

    [C++] User input check

    Siccome capito spesso (a me) di sbagliare a inserire dati manualmente durante un programma volevo creare un metodo che controllasse il type in input. Ho sfruttato l'idea che mi diede MItaly. Ho cmq un problemino in compilazione:

    alla stringa 36 "is>>aux>>std::ws" non riconosce aux e me lo da come undeclared. Come mai? Nel flusso if-else viene sicuramente dichiarato aux. Indipendentemente da questo, se capite l'intento del metodo, cosa cambiereste o come lo impostereste, thx...

    codice:
    void UserInput(string os, int type) {     
         /*The method checks if the user inserts a wrong type variable
           the input "type" is the type to be checked out
           1)int, 2) float, 3) double, 4) char
         */
         string s;
         istringstream is;
         bool check;
         if(type==1){
                     int aux;
                     check = ((!is && !is.eof())||(((int)aux-aux)!=0));
                     }
         else if(type==2){
                          float aux;
                          check = ((!is && !is.eof())||(((float)aux-aux)!=0));
                          }
         else if(type==3){
                          double aux;
                          check = (!is && !is.eof());
                          }
         else if(type==4){
                          char aux;
                          check = (!is && !is.eof());
                          }
         else string aux;
         
         do{
            std::cout << os;
            getline(std::cin, s);
            is.clear();
            is.str(s);
            is >> aux >> std::ws;
            }while(check);
    }
    pensandoci mi viene il dubbio che dichiarando dentro gli if-else lo scope sia ivi limitato....non saprei come fare un cast allora, indizi?
    Ultima modifica di Toxotes; 19-11-2013 a 10:46

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,472
    La dichiarazione di aux è locale al blocco in cui è inserita. Per essere visibile dal do dovrebbe essere fuori dai blocchi (come la check) ma, evidentemente, non potrebbe essere in tutte quelle forme.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    41
    Si infatti...o faccio una classe con dentro i metodi per ogni tipo oppure pensavo di poter risolvere con un cast. tu quindi non hai indizi al riguardo ergo pensi che debba scrivere un metodo per ogni tipo?

    A parte questo come sono scritte le condizioni vi quadrano?

  4. #4
    Perché fai tutto quel pasticcio con gli switch? Rendi la funzione template e il problema finisce lì (e tra l'altro se cerchi in giro avevo già scritto qualcosa del genere, cerca AcquireInput nel forum).
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    41
    eheh MItaly, ma io sono uno smanettone dell'ultim'ora...ora devo capire cosa significa rendere la funzione tmp poi mi leggo Acquire input. Grazie per la dritta. (avevo pensato cmq di dichiarare aux globale come pointer e poi cambiargli tipo ogni volta con new free).


    edit---

    no AcquireInput mi da solo questo 3d.
    Ma in ogni caso, dando una veloce letta a come creare template functions, anche se mi faccio la classe con argomenti diciamo la stringa che voglio dare in out e una variabile del tipo su cui voglio fare il controllo
    codice:
    template <class InputCheck>
    void Check( string os, InputCheck type);
    rimane il fatto che dovrò avere un metodo per ogni tipo o sbaglio?
    cioè quando lo stream is cerca di memorizzare il contenuto in aux mi da errore (e quindi !is è vero) solo se cerco di mettere un char o una stringa in un qualcosa dichiarato come tipo numero (int, float etc.), ma non discrimina il tipo numero...almeno così mi pare. Quindi per discriminare il tipo, generalmente un int da dei floating, ho cmq bisogno di un controllo specifico per quel tipo dico bene?
    Quindi evito il problema dello scope di aux, ma gli switch me li devo cmq tenere uno per ciascun tipo.
    Ultima modifica di Toxotes; 19-11-2013 a 15:54

  6. #6
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    41
    thx

  8. #8
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    41
    Ho letto la tua template e per intenderci, la modifica che volevo apportare ma non mi riesce (o meglio mi riuscirebbe ma perdendo in generalità...) è un qualcosa di questo tipo, in cui si distingue il caso in cui Result debba essere int.

    codice:
    #include <iostream>
    #include <limits>
    #include <string>
    #include <typeinfo>
    
    
        template<typename InType> void AcquireInput(std::ostream & Os, std::istream & Is, const std::string & Prompt, const std::string & FailString, InType & Result)
        {
            bool check;
            double aux;
            do
            {
                Os<<Prompt.c_str();
                if(Is.fail())
                {
                    Is.clear();
                    Is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
                }
                if(typeid(Result).name() == "int")
                {
                    Is>>aux;
                    check = ((Is.fail())||(((int)aux-aux)!=0));
                    }
                else {
                     check = (Is.fail()); 
                     }
                if(check){
                    Os<<FailString.c_str();
                    }
                else{
                     Is>>Result;
                     }
            } while(check);
        }
    
    
        template<typename InType> InType AcquireInput(std::ostream & Os, std::istream & Is, const std::string & Prompt, const std::string & FailString)
        {
            InType temp;
            AcquireInput(Os,Is,Prompt,FailString,temp);
            return temp;
        }
    probabilmente è sbagliato qualcosa, ma è solo per intenderci...
    Ultima modifica di Toxotes; 19-11-2013 a 17:27

  9. #9
    In primis, per verificare se è un tipo particolare a runtime usi if(typeid(nomevariabile) == typeid(tipo)); ma normalmente nei template non si usa typeid, e si ricorre invece a chiamate in overload (che sono risolte a compile time).

    Inoltre, facendo così perdi completamente di generalità - dato che non usi InType quel template lì di fatto si può usare soltanto con tipi numerici. Spiega meglio cosa stai cercando di ottenere.
    Amaro C++, il gusto pieno dell'undefined behavior.

  10. #10
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    41
    Ok scusa (sai l'ignoranza...abbi pazienza). Fondamentalmente voglio anche il controllo sul tipo numerico. Ma la tua funzione che devo dire è davvero ben scritta e ti sono grato di averla condivisia risolve cmq il problema. Semplicemente se una variabile la voglio int dall'utente (è su questo che voglio il controllo, se mi sbaglio a mettere un punto e non me ne accorgo o mi confondo nell'immettere il dato...) la dichiaro float e poi, dopo il check che fa la tua template ho un altro while che va a verificare che sia int attraverso il cast (int)var-var!=0...quindi in qualche modo va benissimo così, grazie ancora.

    codice:
    float var;
    
    do{
         var = AcquireInput(cout,cin,"insert int: ", "invalid input");
    }while( ((int)var-var) != 0 );
    Ultima modifica di Toxotes; 19-11-2013 a 19:09

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.