cin.get counts newline as character?

Hi,

I have the following code:

1
2
3
4
5
6
7
char option;
while(option != 'q')
{
  std::cout << "enter option: \n";
  std::cin.get(option);
  std::cout << '\n';
}


when i run it and enter the character 'a' for example

it outputs:

1
2
3
4
5
6
enter option:
a

enter option:

enter option:


i suspect this is because when i press the 'a' key and then hit the enter key, the input stream reads it as two characters ('a' and the newline character)
So then when the next loop runs the cin.get reads the newline character that is still in the buffer, rather than pause and wait for new input.

but i dont want it to count the newline character as an option

what can i do?
Last edited on
not sure exactly why that behavior happens, since istream get() function is supposed to read a single character. In any case, replace line 5 with std::cin >> option; , which does a formatted input read much more smoothly.
The problem is that cin is buffered, but get reads only one char so the '\n' remains in the buffer.
You could use std::cin.ignore(255, '\n'); to read the '\n'.

If you use Visual Studio and don't care about standard conformity you could use _getch or _getche
An alternative method could be reading each time a whole line.
1
2
3
4
5
6
7
std::string option;
while(option[0] != 'q')
{
  std::cout << "enter option: \n";
  std::getline(std::cin, option);  // reads a whole line
  std::cout << '\n';
}
@nuderobmonkey
1
2
std::string option;
while(option[0] != 'q')

This will crash since the string is empty when you try to read it.
This will crash since the string is empty when you try to read it.

Oops! I thought at the empty string there would be at least a '\0'. I tested for this, and there i always get the '\0' at mine.

1
2
3
4
5
#include <iostream>
int main() {
    string str;
    std::cout << static_cast<int>(str[0]);  // I get always 0 for this.
}
Last edited on
You are right. I also get 0.
This is very strange. Normally the last valid index is size() - 1, so I expected an out_of_range error.
Now I looked up for this topic, and I found at "http://en.cppreference.com/w/cpp/string/basic_string/operator_at" the correct behavior for C++11 and higher:
If pos == size(), a reference to the character with value CharT() (the null character) is returned.

About bounds checking, it says:
No bounds checking is performed. If pos > size(), the behavior is undefined.


Last edited on
Topic archived. No new replies allowed.