Visualizzazione dei risultati da 1 a 10 su 13

Discussione: [C++] std::cin

Hybrid View

  1. #1
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Quote Originariamente inviata da ing82 Visualizza il messaggio
    Ne segue quindi di evitare come la peste cin>>... (cosa che avevi già detto, però che non viene detta ai neofiti da nessuna parte, almeno dove ho guardato io...).
    In realtà l'input è sempre stato una rogna in ogni linguaggio e C++ non fa eccezione. In genere viene sempre insegnato l'uso di operator >> per comodità/ facilità di apprendimento, ma appena si esce dall'ambito scolastico le cose cambiano drasticamente.
    In realtà operator >> va evitato come la peste se il tipo di dato da acquisire è un char, int, double etc; ossia i tipi di dato nativo (tra i quali, e solo in questo singolo caso, si deve porre anche std::string in quanto operator >> tronca l'acquisizione al primo spazio).

    operator >> in realtà è comodissimo se posto in overload con una classe per acquisire input, ma tale classe poi finirà per inserire i dati dentro int, char, float etc, pertanto si torna nel caso precedente.
    Pertanto per evitare di incasinare l'input (cin) è preferibile acquisire l'input come stringa (std::string preferibilmente) e poi effettuare la validazione dell'input su tale stringa (con istringstream o altri metodi più o meno sofisticati).
    Resta il problema di come segnalare un errore di conversione, ma presumo tu sappia come fare

    Stando cosi' le cose la funzione pause potrebbe diventare
    Meglio
    codice:
    void pause()
    {
        cout << "messaggio" << endl;
        int c;
        do {
            c = cin.get();
        } while (c != '\n' && c != EOF);
    
    };
    Per quanto riguarda il resto, non capisco perchè mi consigli di usare ostringstream e non istringstream.
    Errore mio dovuto al post al volo.

    Ad esempio, per l'input degli int potrebbe essere una cosa del genere (?):
    Così è più flessibile. Tuttavia se chiedi un int e immetti un float, la funzione non fallisce ma fa un cast tra float e int, ossia 3.56 diventa 3, mentre se chiedi un float e inserisci un int il cast e da int a float, ossia 3 diventa 3.000000.
    E' una validazione dell'input un pò blanda, ma evita che inserendo o.004 invalidi cin.
    Se hai bisogno di qualcosa di più sofisticato, istringstream non basta più e serve scriversi la validazione dell'input a "mano".
    p.s. ho messo sia il throw, sia la booleana. Decidi tu cosa lasciare.
    codice:
    template <typename T>
    T read(std::istream& is, bool& valid ) {
        // be optimistic
        valid = true;
        std::string line;
        do {
            getline(is, line);
        } while (line.empty());
    
    
        T data;
    
        istringstream iss(line);
        iss >> data;
        if (!iss) {
            valid = false;
    //        throw std::logic_error("invalid input");
        }    
        return data;
    }
    
    // per simmetria
    template <> 
    std::string read(std::istream& is, bool& valid) {
        valid = true;
        std::string line;
        do {
            getline(is, line);
        } while (line.empty());
        return line;
    }
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  2. #2
    Utente di HTML.it L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177
    Credo di dover studiare tutta la combricola degli stream, qualche suggerimento di supporto valido (libri, link, ecc)? e se poi, oltre alla teoria, ci scappa anche qualche esempio ben studiato (intendo ovviamente nel materiale che mi verrà indicato, non vi chiedo di farmeli voi), meglio ancora...

    Poi spero di vernirne a capo di sta storia dell'input...

    Grazie

  3. #3
    Utente di HTML.it L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177
    Quote Originariamente inviata da shodan Visualizza il messaggio
    codice:
    template <typename T>
    T read(std::istream& is, bool& valid ) {
        // be optimistic
        valid = true;
        std::string line;
        do {
            getline(is, line);
        } while (line.empty());
    
    
        T data;
    
        istringstream iss(line);
        iss >> data;
        if (!iss) {
            valid = false;
    //        throw std::logic_error("invalid input");
        }    
        return data;
    }
    Il dubbio principale e':

    fatico a capire is come parametro: credo possa tornare utile in quanto a read potranno essere passati indifferentemente cin, ifstream e istringstream, in base alle esigenze. Ma sono proprio queste esigenze che non capisco...(sara' la somma di ignoranza e inesperienza, infatti coi file ci ho lavorato pochissimo, praticamente niente, mentre davvero niente con istringstream...)

    Grazie

    Trovato il libro consigliato, sto leggendo, ma l'inglese non mi e' molto d'aiuto nella velocita' di lettura...
    giaà che c'ero ho scaricato anche il volume1, che c'e' pure tradotto in italiano
    Ultima modifica di LeleFT; 28-07-2016 a 10:36

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 © 2026 vBulletin Solutions, Inc. All rights reserved.