explanation of a code

Hi, I am learning about get() and getline() in c++. The book I was following had an example that I didn't quite understand. Here is the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  // numstr.cpp -- following number input with line input
#include <iostream>
int main()
{
  using namespace std;
  cout << "What year was your house built?\n";
  int year;
  cin >> year;
  cout << "What is its street address?\n";
  char address[80];
  cin.getline(address, 80);
  cout << "Year built: " << year << endl;
  cout << "Address: " << address << endl;
  cout << "Done!\n";
  return 0;
}


Then it gives the following explanation:
You never get the opportunity to enter the address. The problem is that when cin reads the
year, it leaves the newline generated by the Enter key in the input queue. Then,
cin.getline() reads the newline as an empty line and assigns a null string to the address array. The fix is to read and discard the newline before reading the address.

What I don't understand is why would the compiler accept the 'Enter key' pressed after the year input (cin >> year), as the address, even before declaring the address array?
Also, I realise that get(), getline(), or get(ch) solves the problem. I have another doubt, do we have to declare
char ch; to use get(ch); ?

Thanks in advance, I apologize for the lengthy questions.

Last edited on
The input you give to the program could be anything. It doesn't have to match the way you use cin or anything. You can even give input without using cin in your program.

cin simply reads the input as a long sequence of characters. If there is not enough characters to read it will wait for the user to enter more input.
It's because I/O is done through a stream which persists throughout the program's lifetime, and functions like getline() read until they hit a delimiter (default is the newline character). This means the function will read until it sees the delimiter and then exit, leaving that delimiter in the stream. Since it would be unruly for a program to just drop random characters in the stream without your permission, it stays until you do something about it.

If you leave that delimiter in the stream, the next time you call some method for reading from that stream the very first character you get back will be the delimiter, which will cause the function to stop reading.

I have another doubt, do we have to declare
char ch; to use get(ch); ?

Nope. istream::get has an overload which returns an integer representation of the next character in the stream, taking zero parameters.
Last edited on
why would the compiler accept the 'Enter key' pressed after the year input (cin >> year), as the address, even before declaring the address array?

It has to do with the way streams are implemented. streams are simply a buffer of characters. cin >> year reads numeric characters from the buffer and stops when it sees the next character is not numeric. You can skip the newline by doing get(ch), but the more common solution is to use:
1
2
3
 
  cin.clear();  // Clear any error flags
  cin.ignore ( 100, '\n');  // discard upto 100 characters or until newline 


BTW, this is done by the run-time library, not the compiler.

do we have to declare char ch; to use get(ch); ?

Yes.
Last edited on
Thanks for the help. I think I understood. Basically, the newline remains in the stream, which is then taken as input for the address array. But, cin.get() accommodates the new line which is in the stream, and allows the address array to take input from the user.
But, cin.get() accommodates the new line which is in the stream, and allows the address array to take input from the user.

Yes, but. What if the user entered 12a for year? The a and the newline would both be left in the buffer, which is why I said cin.ignore(100,'\n') is preferred.

Regarding the discrepancy between ResidentBiscuit's response and mine regarding get(ch):

You specifically asked about calling get(ch) with a variable as an argument. In that case, the variable must be defined. As ResidentBiscuit pointed out, you can call get() with no argument and it will eat one character from the input buffer. However, as I pointed out above, you have no guarantee that next character is a newline.

Last edited on
Thanks again!
Topic archived. No new replies allowed.