Quando si legge uno stream, per esempio quando si effettua un input da tastiera o si legge un file di testo, se lo stream di input contiene caratteri quali spazi, tabulazioni (‘\t’ – tasto tab) o nuova linea (‘\n’ – tasto invio), si faccia attenzione perché questi vengono interpretati dall’operatore di lettura C++ (>>) e dalla funzione scanf() del C, come dei caratteri di fine stringa. Pertanto se si vuole acquisire correttamente un input che potenzialmente può contenere questi caratteri, l’operatore di lettura e la scanf() non possono essere utilizzati.
Caso delle C-string
Quando si lavora con le stringhe in stile C (link articolo) si può utilizzare il metodo cin.getline() che ha la seguente sintassi:
cin.getline(char* str, int n, char delim);
- str è un puntatore ad un char, ossia il nome di un vettore di char (la stringa in stile C) in cui memorizzare la stringa letta dallo stream associato all’oggetto cin;
- n è pari al numero di caratteri da leggere più uno (questo perché ai caratteri letti viene automaticamente aggiunto il carattere terminatore di stringa ‘\0’ ); tipicamente n è la dimensione del vettore di char, str;
- delim (opzionale) è il carattere delimitatore fino al quale si vuole leggere nello stream (di default è il carattere ‘\n’ di nuova riga). Se nello stream trova il carattere delimitatore, lo estrae dallo stream e lo scarta.
- Si noti che il metodo cin.getline() riscrive str facendole perdere il contenuto precedente.
Esempio.
1 2 |
char nome_cognome[40]; cin.getline(nome_cognome, 40); |
NOTA – Quando si utilizza il metodo getline(), si faccia attenzione alle letture realizzate con l’operatore di lettura (<<). Esso, infatti, quando incontra il carattere ‘\n’ non lo elimina dal buffer dello stream di input, per cui una successiva lettura con il metodo getline() non va a buon fine in quanto viene incontrato il carattere ‘\n’. In questi casi prima di eseguire una getline(), bisogna eliminare dal buffer i caratteri di nuova riga residui. Ciò può essere fatto in vari modi, ad esempio con il metodo cin.ignore():
1 |
cin.ignore(100, '\n'); //100 è il numero massimo (ritenuto sufficientemente grande) di caratteri da eliminare prima che si incontri il carattere '\n' |
oppure con il seguente ciclo:
1 |
while(getchar() != '\n'); |
Caso delle stringhe in stile C++
Quando si opera con le stringhe in stile C++ (link articolo) si può utilizzare la funzione getline() che ha la seguente sintassi:
getline (istream& is, string& str, char delim);
- is è lo stream dal quale leggere l’input;
- str è la stringa in stile C++ in cui memorizzare la stringa letta fino al primo ‘\n’, se non si utilizza il terzo parametro delim, o altrimenti fino al primo carattere delim; in quest’ultimo caso una successiva getline() parte a leggere dal primo carattere successivo al carattere delim incontrato dalla precedente getline();
- delim (opzionale) è il carattere delimitatore fino al quale legge lo stream che memorizza nella stringa str (di default è il carattere ‘\n’ di nuova riga). Se nello stream trova il carattere delimitatore, lo estrae dallo stream e lo scarta.
- Si noti che la getline() riscrive str facendole perdere il contenuto precedente.
Esempi.
1 2 3 4 5 6 7 8 9 10 11 |
#include <iostream> #include <string> //libreria C++ using namespace std; int main() { string s; cout << "Inserisci nome e cognome: "; getline(cin, s); cout << s << ", benvenuto!"; return 0; } //Se l'INPUT è: Mario Rossi, l'OUTPUT sarà: Mario Rossi, benvenuto! |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <iostream> #include <string> using namespace std; int main(){ string s1, s2; getline(cin, s1, ';'); getline(cin, s2); cout<<s1<<endl; cout<<s2<<endl; return 0; /*** In corrispondenza di questo INPUT: input n.1;input n.2 il programma produce il seguente OUTPUT: input n.1 input n.2 ****/ |