PDA

Visualizza la versione completa : [C++] Uso di cin e carattere "new line"


elettrika33
18-02-2011, 18:53
Salve, mi trovo davanti ad un problema stupido, vi riporto qui di seguito un esempio



#include <iostream>
#include <cstring>

using namespace std;

int main()
{
int a;
char parola[10];

cin >> a;
cin.getline (parola, 10);

return 0;
}


ho sempre utilizzato sia il cin classico che il getline, e non credo di aver mai incontrato problemi, ho provato lo stesso pezzo di codice su diversi computer e il risultato è sempre lo stesso, mi fa inserire la prima variabile, ma quando dovrebbe inserire il getline si blocca, può essere che sia un problema di dev? Perchè vi giuro che non riesco proprio a capacitarmene...

shodan
18-02-2011, 20:17
Originariamente inviato da elettrika33
può essere che sia un problema di dev?

Dev di suo è un problema, ma in questo caso non centra.
Usando gli estrattori di cin è facile che rimanga il newline nel buffer interno, che poi fa saltare il successivo inserimento.
Un modo per risolvere è:


int main()
{
int a;
char parola[10];

cin >> a;
cin.ignore(LONG_MAX,'\n');
cin.getline (parola, 10);

return 0;
}

elettrika33
18-02-2011, 20:38
Ti ringrazio per la risposta, mi spiegheresti brevemente come funziona il comando cin.ignore? Dovrei anteporlo ad ogni cin.getline?

Non ci sarebbe in caso un altro modo per ovviare al problema? Mi servirebbe saperlo per un progetto universitario dato che il cin.ignore non è stato spiegato a lezione...

shodan
18-02-2011, 21:05
Il cin.ignore()
http://www.cplusplus.com/reference/iostream/istream/ignore/
serve per scartare un carattere specifico. Quando acquisisci un valore tramite l'operatore>>, ti viene restituito quel valore (se valido), ma il carattere di newline '\n' rimane nel buffer. Alla successiva lettura, cin legge per primo il '\n' e pensa che l'input sia finito. Una successiva lettura "dovrebbe" invece essere corretta.

Un altro modo può essere cin.sync()
http://www.cplusplus.com/reference/iostream/istream/sync/

Altrimenti:


while ( cin.get() != '\n' );

dovrebbe essere sufficiente.

Dove metterlo? Dopo aver usato l'operatore >> (altri casi dovrebbero essere "safe").

elettrika33
19-02-2011, 13:51
Ok, ti ringrazio nuovamente. Posso chiederti perché magari in programmi molto complessi non mi si è presentata questa situazione e in queste poche righe di codice sì? Forse perché sono due istruzioni consecutive?

shodan
19-02-2011, 14:17
Dipende da quanti input fai e se usi spesso gli estrattori. Con cin.getline() non si verifica ad esempio. Purtroppo cin accoppiato agli estrattori è abbastanza rognoso da gestire bene.
Molti preferiscono acquisire una stringa con cin.getline() (o usare direttamente una std::string) e lavorare sul buffer acquisito, per gestire il loro input. Per lo meno si evita il comportamento da te descritto e/o di mandare in errore lo istream.

elettrika33
19-02-2011, 14:36
Quindi mi converrebbe usare sempre il getline anche quando vado a leggere un singolo carattere o una sola parola?

shodan
19-02-2011, 14:50
In progetti semplici puoi usare anche gli estrattori. In progetti dove se sbagli l'input succede un disastro, meglio getline (disastro è anche presentare un programma malfunzionante al proprio professore, essendo convinti di averlo fatto bene).

Loading