Cercavo un'alternativa a system("PAUSE"), e mi sono strovato ad affrontare due problemi, uno proprio il creare un qualcosa di multipiattaforma che sostituisse system("PAUSE") e l'altro, la validazione dell'input.
Il risultato e' riportato sotto ed e' stato ottenuto mettendo assieme quanto trovato ingiro, tentativi vari e documentazione (alla fine qualche autocritica).
Si accettano, in realta' aspettano, critiche, correzioni, spiegazioni e quant'altro possa migliorare quanto sotto riportato.
codice:
void pause()
{
std::cout<<"\nPremere INVIO per continuare\n";
std::string input;
if(std::cin.fail())//se cin e' in errore, lo si sistema
{
std::cin.clear();
}
if(std::cin.gcount()!=0)//se cin ha qualche carattere, lo svuoto
{
std::cin.ignore(1000,'\n');//1000 andrà sostituito quanto meno con una macro, o ancora meglio con gli standard limits.
//ho trovato chi consiglia di usare rdbuf()->inavail(), ma non mi funziona...
}
while(std::getline(std::cin , input))//in questo modo qualsia input dato con cin, viene tutto riversato in input, quindi cin dovrebbe essere vuoto dopo l'esecuzione del comando
{
if (input.length()==0)//l'unico modo per avere input.length()==0 è premere invio senza alcun tasto
{
break;
}
std::cout<<"\nInput errato\n";
}
};
Successivamente mi sono posto il problema di validare l'input, e sono arrivato a produrre quanto sotto.
Funziona con int, float, double, char e string.
Non funziona con gli unsigned int: se infatti inserisco un numero negativo, viene restituito un intero positivo che credo sia il max int a cui sommo con segno il numero immesso (fate una prova usando come par un unsigned int)
codice:
template <typename T>
static void input(T& par)
{
std::string input;
if(std::cin.fail())//se cin e' in errore, lo si sistema
{
std::cin.clear();
}
if(std::cin.gcount()!=0)//se cin ha qualche carattere, lo svuoto
{
std::cin.ignore(1000,'\n');//1000 andrà sostituito quanto meno con una macro, o ancora meglio con gli standard limits.
//ho trovato chi consiglia di usare rdbuf()->inavail(), ma non mi funziona...
}
while(std::getline(std::cin,input))//in questo modo qualsia input dato con cin, viene tutto riversato in input, quindi cin dovrebbe essere vuoto dopo l'esecuzione del comando
{
if((typeid(par).name()==typeid('a').name())&&(input.length()==1))//se par e' di tipo char e ho dato un solo tasto di input
{
par = input[0];
break;
}
else
{
std::stringstream linestream(input);
if ((linestream >> par)&&(linestream.eof()))//linestream>> dovrebbe restituire errore se passo una lettera a un int
{
break;
}
}
std::cout<<"\nInput errato\n";
}
};
Ed ora autocritica:
- il controllo con gcount e' stato messo perche' se metto come prima riga del programma pause senza prima aver fatto altro input, e metto solo cin.ignore, servono due invio per proseguire, cin.ignore lo ho messo nel caso sia stato usato cin>> in precedenza e siano stati digitati più input di quanti ne servissero (ad esempio se cin>> tipo_char ma immetto 'aaa', devo svuotare perchè mi restano in cin ancora 'aa'.
- dopo clear, vedo che spesso viene consigliato di usare sync, ma sinceramente non riesco a capire cosa fa, anche perchè qui non usandolo sembra che quanto fatto funzioni.
- resta aperto il problema degli unsigned int
- resta aperto il problema, devo ancora pensare/provare, nei casi in cui par potrebbe essere un enum.
Grazie