2013-09-28 29 views
6

Con scanf è permesso di ignorare gettoni abbinati, semplicemente aggiungendo * al modello, come in:Ignorando/saltare i token utilizzando std :: cin

int first, second; 
scanf("%d %*s %d", &first, &second); 

Esiste un approccio equivalente con std::cin? Qualcosa di simile (ovviamente, risparmiando l'utilizzo di ulteriori variabili):

int first, second; 
std::cin >> first >> `std::skip` >> second; 

risposta

3

Non è un compito semplice per i flussi di input in C++ fare la stessa cosa. La funzione scanf ottiene tutto il formato previsto: "%d %*s %d" e può guardare avanti per determinare cosa sta succedendo.

D'altra parte, l'operatore >> tenta semplicemente di soddisfare il parametro di immissione corrente.


Hai la possibilità di scrivere il tuo manipolatore istream per mangiare gli input fino a raggiungere una cifra.

Prova questa mio codice ingenuo:

template<typename C, typename T> 
basic_istream<C, T>& 
eat_until_digit(basic_istream<C, T>& in) 
{ 
    const ctype<C>& ct = use_facet <ctype<C>> (in.getloc()); 

    basic_streambuf<C, T>* sb = in.rdbuf(); 

    int c = sb->sgetc(); 
    while (c != T::eof() && !ct.is(ctype_base::digit, c)) 
     c = sb->snextc(); 

    if (c == T::eof()) 
     in.setstate(ios_base::eofbit); 

    return in; 
} 

int main() 
{ 
    int first, second; 

    cin >> first >> eat_until_digit >> second; 

    cout << first << " : " << second << endl; 
} 

È possibile estendere e migliorare sopra codice per ottenere quello che ti serve.

+0

+1 Suoni ragionevoli! ^^ E che dire un insieme di salti, come 'std :: ios :: skip :: str',' std :: ios :: skip :: dec', e anche 'std :: ios :: skip :: any'? Troppo disordinato? (: – Rubens

+1

@Rubens: vedere la mia risposta aggiornata, seconda parte. – deepmax

+0

Non 'std :: ctype :: scan_is' fare questo? – 0x499602D2

3

Probabilmente si sta cercando C++ String Toolkit Library.

Controllare questo per più example

Oppure si può provare con ignore funzione come questa:

std::cin >> val1; 
std::cin.ignore (1234, ' '); 
std::cin >> val3; 

Qualcosa di simile a questo: -

template <class charT, class traits> 
inline std::basic_istream<charT, traits> & 
ignoreToken (std::basic_istream<charT, traits> &strm) 
{ 
    strm.ignore (1234, ' '); 
    return strm; 
} 

E poi usare come:

cin >> val1 >> ignoreToken >> val3 >> ignoreToken >> val5; 
+0

Anche se sembra essere l'unica opzione disponibile da stl, mi aspettavo qualcosa di un po 'più nutriente. Un 'std :: ios :: skip :: str' e' std :: ios :: skip :: dec' e anche 'std :: ios :: skip :: any' sarebbe molto bello (: – Rubens

+0

@Rubens: - Questo mi aiuta ora? –

+1

+1 Non ho mai voluto dire che il tuo post non ha aiutato! ^^ Grazie per l'esempio funzionale! (: – Rubens

2

si può semplicemente utilizzare una variabile dummy

int first, second; 
std::string dummy; 
cin >> first >> dummy >> second; 

ma non c'è alcun equivalente per quanto ne so diretta.

+0

Sì, è per questo che ho indicato " * naturalmente, risparmiando l'uso di ulteriori vars * ". Mi sto abituando all'idea che questa sia l'unica soluzione, comunque \ = – Rubens

+0

@Rubens, mi dispiace non averlo visto. – john