Newsgroup: it.comp.lang.c++
Titolo: [Banale(?)]Inserisci il tuo nome!

PREMESSA--> mi scuso se affronto un thread trito e ritrito: ne ho letti
molti sull'argomento -a dimostrazione che questo è un problema evidentemente
comune tra i newbie (come me)- ma purtroppo non ho tratto indicazioni da
alcuno per risolvere questa questione.
Salve a tutti, sono alle prese con un programma che richiede input da
tastiera e mi trovo ad avere a che fare con i soliti problemi legati a
cin...getline...get...\n...e buffer che non si svuotano: preferirei
risolvere i problemi che mi si presentano in maniera radicale, piuttosto che
mettere delle 'pezze' quando necessario. Allora:
**Cosa deve fare il programma: il programma deve accettare in ingresso una
stringa 'nome' (che presumibilmente rappresenta il nome dell'utente) ed una
stringa 'nick' (che verosimilmente ne rappresenta il nick).
**Qual è il problema?! Non conosco a priori la dimensione delle stringhe
inserite dall'utente, nè so se queste sono parole singole o più parole
separate da spazi (ad esempio l'utente inserisce -cosa lecita- nome e
cognome nel campo nome...o un nick di 2 parole)
Per la questione della dimensione, credo che si debba definire un array di
caratteri di dimensioni 'opportune', magari prevedendo il caso 'peggiore' di
nomi lunghissimi e mettendo un certo margine: avevo pensato a definire 2
array di 30 caratteri. Per la questione delle parole e degli spazi invece è
buio pesto...avevo pensato a diverse soluzioni, ma tutte presentavano
problemi:
Dopo aver definito
    char nome[30];
    char nick[30];
soluzione1)
    cout<<"Inserisci il nome: ";
    cin>>nome;
    cout<<"Nome: "<<nome<<endl;
    cout<<"Inserisci il nick: ";
    cin>>nick;
    cout<<"Nick: "<<nick<<endl;
problema (banale): se l'utente inserisce nel campo 'nome' 2 parole separate
da spazio, in nome va la prima parola ed in nick va la seconda...cioè viene
saltato il secondo cin
soluzione2)
sostituisco nel listato precedente
i 2 cin con cin.getline(nome,30)
ora tutto funziona se l'utente immette stringhe lunghe fino a 29 caratteri,
ma per stringhe più lunghe in nome vanno i primi 29 caratteri (e questo mi
sta anche bene)...il problema è che viene saltato il secondo getline e nick
è così una stringa vuota. Non capisco (tra le altre cose) perchè il secondo
getline non prelevi dallo stream, visto che questo dovrebbe non essere vuoto
(dovrebbe contenere i caratteri in eccesso).
Come risolvo il problema?
Grazie in anticipo per i suggerimenti e scusate ancora la banalità della
domanda.

#include <iostream>
#include <string>
int main() {
 string nome, nick; <--- In C++ non devi usare array di char ma stringhe
 std::cout << "Nome?" << std::endl;
 getline (std::cin, nome, '\n'); <---- Memorizza la stringa fino al "a capo"
 std::cout << "Nick?" << std::endl;
 getline (std::cin, nick, '\n'); <---- Idem
 std::cout << "Il tuo Nome e' " << nome << std::endl;
 std::cout << "Il tuo Nick e' " << nick << std::endl;
 return 0;
}
Ciao

  getline (std::cin, nome, '\n'); <---- Memorizza la stringa fino al "a
capo"
non pensavo ad un metodo così comodo! Qual è il limite di caratteri per la
stringa?
comunque sei stato preziosissimo: grazie! Oltre ad aver risolto il mio
problema mi hai anche fatto 'affacciare' sulla classe string. Approfitto per
chiederti chiarimenti sulle righe di codice da te postate:
-Gli header senza estensione .h sono le librerie standard del C++ (vs quelle
con estensione .h che sono le librerie del C)? Se così fosse, capisco string
che è diversa da string.h, ma non capisco iostream (è uguale ad iostream.h?)
-getline (std::cin, nome, '\n'); <---- Memorizza la stringa fino al "a capo"
il problema è che memorizza anche eventuali 'a capo' terminali (ad esempio
se scrivo "argo " memorizza "argo ")...è facile creare una funzione ad hoc
che eviti questo, ma mi chiedevo se non esisteva già un metodo che non
considerava gli 'a capo' terminali.
ancora grazie : )
Ciao.
argo(n)

 ancora grazie : )
Umh... non saprei, comunque e' molto semplice in questi casi aggirare il
problema, in vari modi ad es.:
string s = "";
 getline (std::cin, s, '\n');
 int i = s.size();
 while (s[--i] == ' ')  // va a ritroso partendo dalla fine
  s.erase(i); // se e' uno spazio lo cancella
Oppure volendo usare 2 metodi della classe string:
string s = "";
getline (std::cin, s, '\n');
s = s.substr(0, s.find_last_not_of(" ") + 1); // s non contiene gli spazi
finali
La funzione s.find_last_not_of(" ") restituisce l'indice in cui si trova
l'ultimo carattere della stringa che non e' uno spazio.
La funzione s.substr(x, y) estrae una sottostringa di s, a partire da
l'x-esimo carattere, y caratteri. Combinandole tra di loro ottieni l'effetto
voluto :)
Cmq se vuoi apprendere il C++ devi comprare una buona guida oppure cercare
risorse in rete (in inglese c'e' Thinking in C++ di Bruce Eckel)
Ciao

 Qual č il limite di caratteri per la stringa?
#include <iostream>
#include <string>
int main()
{
    std::string s;
    std::cout << s.max_size() << '\n';
    return 0;
}
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg

 math.h diventa cmath
C'é da dire, per la sezione cose-buone-a-ricordare, che
<ctype.h> del C é adesso <cctype> con due c, e cosí per altri moduli
simili.
-- 
Adriano Varoli Piazza
The Inside Out: 
http://moranar.com.ar
MSN: 
adri...@hotmail.com
ICQ: 4410132

 , dove c'è un mio piccolo
intervento con codice di esempio su uno dei possibili corretti utilizzi di
cin.getline(). Per comprendere meglio la risposta dai anche uno sguardo alla
domanda iniziale del thread. Comunque in sintesi si trattava di un
programmatore che aveva dei problemi appunto nell'utilizzo di questa
funzione e asseriva che il programma "saltava la getline()".
Buon lavoro,
fabio de francesco
(fabiomdf)
 
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/