2

I've written some code to detect empty user input:

if(cin.get() == '\n')
{
   cout<<"ENTER WAS PRESSED"<<endl;
}

But for some reason if the user presses ENTER it just keeps advancing to the next line as I press ENTER.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
user2529011
  • 705
  • 3
  • 11
  • 21
  • 1
    I think you have to use noskipws or something along those lines. By default cin skips whitespace and \n is whitespace IIRC. – Borgleader Jul 12 '13 at 19:20
  • Sorry I forgot to mention that the user is supposed to enter a number and I wanted to know what to do in order to make sure that if the user presses ENTER then the warning message pops up – user2529011 Jul 12 '13 at 19:24
  • Keep asking until you get what you want? – Borgleader Jul 12 '13 at 19:26
  • @Borgleader: Whitespace and `/n` are different entites. They are treated differently by the compiler. Also, The ASCII value of whitespace is 32 while that of `\n` is 10. – chosentorture Jul 12 '13 at 23:19
  • @ChosenTorture: The C++ compiler treats `\n` as whitespace for all contexts discussed here. – Puppy Jul 12 '13 at 23:50

2 Answers2

8

In this form your code works for me:

#include <iostream>

int main() {
    while (true) {
        if (std::cin.get() == '\n') {
            std::cout<<"ENTER WAS PRESSED"<<std::endl;
        }
    }
    return 0;
}

However, your further comments reveal that your code also includes this:

    while(!(cin >> number) || (number < 0 || number > 3) || (cin.get() == '\n'))

There is your trouble.

What you are trying will not work with that particular while, but many first-term students of C++ ask similar questions, so let me explain. The reason that it will not work is that your concept of std::cin is vague. (By the way, std::cin, please, or cin preceded by using std::cin; if you must. The textbook that is telling you to issue using namespace std; should be burned.)

The object std::cin is a stream—from your perspective, a queue from which your program can accept available input characters when it wishes to do so. Important: std::cin is not a command or an operation, but an object called a stream. By analogy with speech, you may be thinking of std::cin as a verb, only it isn't: it is a noun. By itself, std::cin does not do anything.

What does do something is the extraction operator >>. What also does something is the single-character fetching member function .get(). Both of these retrieve previously unseen characters from the stream std::cin. So, the >> retrieves some characters which the program puts into number, then tests. Then the .get() retrieves another, previously unseen character, which the program checks to see whether it is a newline. But why does your program treat the former group of characters as a possible number and the latter, single character as a possible newline? How does it know that the former group of characters does not begin with a newline?

My suggestion is to try some simpler test programs for a while, using either >> or .get(), but not both in the same program. For now, using both at once is understandably confusing you. Stream input can be tricky. You are unlikely to benefit from further explanation until you get this point straight in your mind, and that will probably take you an hour of trial and experiment. Good luck.

thb
  • 13,796
  • 3
  • 40
  • 68
  • I have mine in a while loop – user2529011 Jul 12 '13 at 19:26
  • while(!(cin >> number) || (number < 0 || number > 3) || (cin.get() == '\n')) – user2529011 Jul 12 '13 at 19:27
  • Also newb here: Why shouldn't you use "using namespace std;"? – UeliDeSchwert Nov 25 '17 at 14:00
  • 1
    @Bobby: Because "using namespace std;" dumps the standard namespace. It disables the namespace mechanism of C++ with respect to standard library symbols. Suppose for example that you have defined a function `bar()`. Suppose that you inadvertently refer to it later as `baz()`. No problem, right? The compiler will flag this for you. However, suppose that the standard library offers a `std::baz()`. What happens after "using namespace std;"? Better is "using std::baz;" which, instead of dumping hundreds of standard library symbols the programmer does not know, imports only the one desired symbol. – thb Jan 10 '18 at 11:31
  • 1
    @Bobby: C++ was a commercial success before being adopted as an instructional language. Unfortunately, in the U.S. academic market, one of the first widely used textbooks (I will spare it the embarrassment of naming it here), which is still fairly widely used, was opportunistically introduced into the then void of available collegiate C++ textbooks *by an author who did not really know C++*. That author had the student dump the namespace. Dumping the namespace is an anti-idiomatic hack in C++. I would not recommend it. – thb Jan 10 '18 at 11:36
  • Thanks for clarification! Makes sense. – UeliDeSchwert Jan 10 '18 at 15:06
4

I think this code does your job.

#include <iostream>
#include <sstream>

using std::cin;
using std::cout;
using std::string;

int main()
{
    string in = "";
    int n = 0;
    while (true)
    {
        cout << "Please enter a number: ";
        getline(cin, in);
        std::stringstream s(in);
        if (s >> n)
            break;
        cout << "Invalid number, please try again\n";
     }
     return 0;
}

AFAIK, I think that you shouldn't use the get() function to input numbers. The get() function is designed to input characters and it behaves as an Unformatted Input Function. The >> operator seems better for this job. The extraction operator >> will wait for your input if you press the ENTER key because it will ignore it. However, the newline input is stored in the cin input stream. You can also try a combination of the peek() and the seekg() function to check for an existing newline input in the input stream and do what you want.

chosentorture
  • 329
  • 2
  • 13