The problem is in cin.get
and how it works. Actually mixing different forms of readings:
cin >>
cin.get
As a general rule, it creates complications, because there are scenarios where they do not behave in the same way.
I will begin by quoting documentation about the cin.get
in an important detail:
The delimiting Character is not extracted from the input Sequence if found, and remains there as the next Character to be extracted from the stream
In free translation:
The delimiter is not extracted from the input sequence if it is found, and remains in it staying as the next character to be extracted.
So it turns out that when you read the first code with cin >> a[i].cod
the \n
stays in the lobby, and then when it goes with the cin.get
does not read anything because the \n
is the first character and is therefore a delimiter. And the cin.get
also does not remove it from the entrance creating a vicious cycle until the end.
After realizing the problem has some solutions.
cin.ignore
the cin.ignore
allows you to discard characters from the input, and can even specify how many you want to discard. In your case you just need to discard one that matches \n
, that has to be done in the right place:
for(int i=0;i<3;i++){
cout << "Nome: ";
cin.get(a[i].nome, 50);
cout << "Cód: ";
cin >> a[i].cod;
cin.ignore(); // <-- consumir a quebra de linha que ficou aqui
}
Watch it work on Ideone
Read everything with >>
If you do all the readings in the same general way it works right as everyone consumes the breaks in the same place.
It is important to mention that in a reading of string
this can be limiting if you want the string to have spaces, because this reading only reads into space, that is, only one word.
If this is not the case it works perfectly, see the example:
for(int i=0;i<3;i++){
cout << "Nome: ";
cin >> a[i].nome; // agora com >>
cout << "Cód: ";
cin >> a[i].cod;
}
Check it out at Ideone
Using std::string
In C++ it has better way to store strings, which is to use std::string
and simplifies your life, avoiding having to control string terminators, and other details.
It is interesting to mention this because it ended up making a common mistake precisely at this point, because the reading of the nome
puts an additional terminator in the string, so you have to read 49
characters and not 50
to prevent it from leaving the allocated space.
If you change the field of the structure to std::string
can do the reading with std::getline
and everything gets simpler:
//...
struct Agenda{
string nome; // agora string
int cod;
};
int main(){
Agenda a[3];
for(int i=0;i<3;i++){
cout << "Nome: ";
getline(cin, a[i].nome); //leitura com getline
cout << "Cód: ";
cin >> a[i].cod;
cin.ignore(); //ignore na mesma
}
//...
See also on Ideone
Using Cin.getline(a[i].nome, 50); I was able to write a second name, but it turns out the same.. I hope I helped with ideas
– André
Here’s my problem. Using the Cin object attached, just passing a string with no spaces, with you. Otherwise, no
– Dan