Input stream's get function doesn't wait for input

The following program tests the standard input stream's get(c) unformatted I/P function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>         /// cin, cout

using namespace std;

/// test the get(c) stream member function
void get0()
{
    char c;

    cout << "Please type some characters: ";
    cin.get(c);

    cout << "the 1st "
         << " character typed: "
         << c << endl << endl;
}


int main()
{
    get0();
}


http://coliru.stacked-crooked.com/a/13e179eb397aece4


The output is as follows:


Please type some characters: the 1st  character typed:



My observations (and queries) are as follows:
1) On examining this code, I feel it is working as it should (though not as intended by me). cin 's stream buffer is empty; therefore cin.get(c) returns a null string, which is then displayed. I think this is how the function is expected to work, right?

2) What I would like to do, however, is to use the unformatted I/P get() function to read cin, while waiting for the user to enter data. I feel this may not be possible using the unformatted I/P get() function with cin. Is this correct? Is there any way to do so?

If not, it would mean that the unformatted I/P get() functions can be used (to get the intended behavior noted above) only with input string streams and input file streams, but not with cin. Is this correct?

Thanks.
If you set an input to be "typed in", you get a different result:

https://ideone.com/iHIRVA


Online compilers and runners often provide empty input to the program being run if the user doesn't state what input to provide. You're better off running your code locally.
Last edited on
Not sure I understand what you mean.

When I run the program, it waits, I type a character and then press enter. Then it prints the character.
Please type some characters: q
the 1st  character typed: q
It works offline on my local copy of g++.

However, it wasn't working online.

Also, offline, there are still some complications: if you sequence 2 functions that use unformatted I/P, the 1st works, but not the second:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>         /// cin, cout

using namespace std;

/// test the get(c) stream member function
void get0()
{
    char c;

    cout << "Please type some characters: ";
    cin.get(c);

    cout << "the 1st "
         << " character typed: "
         << c << endl << endl;
}


/// test the get(p, n) stream member function
void geta()
{
    char word[10];
    int n = 5;

    cout << "Please type some characters: ";
    cin.get(word, n);

    cout << "the 1st " << n - 1
         << " characters typed: "
         << word << endl << endl;
}


int main()
{
    get0();
    geta();
}


Running this offline, get0() works, but not geta().
You are leaving '\n' , the end of line character, in the cin buffer.

When geta() reads from cin, it reads as far as '\n'. Which is at the front of the buffer, having been left there by get0(), so geta() reads nothing.

https://stackoverflow.com/questions/257091/how-do-i-flush-the-cin-buffer
Last edited on
I have modified the program to clear the input buffer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>         /// cin, cout
#include <climits>             /// INT_MAX

using namespace std;

/// test the get(c) stream member function
void get0()
{
    char c;

    cout << "Please type some characters: ";
    cin.get(c);

    cout << "the 1st "
         << " character typed: "
         << c << endl << endl;
}


/// test the get(p, n) stream member function
void get1()
{
    char word[10];
    int n = 5;

    /// Skip the rest of the buffer.
    cin.ignore(INT_MAX);

    cout << "Please type some characters: " << endl;
    cin.get(word, n);

    cout << "the 1st " << n - 1
         << " characters typed: "
         << word << endl << endl;
}


int main()
{
    get0();
    get1();
}


https://ideone.com/ApjUSR

However, there's still a problem, both online as well as offline:
1) In the 2nd function get1(), an output prompt should have appeared followed by the user being allowed to enter some chars. (That's the sequence in which these statements are specified.) Instead, in the local program, the program pauses for user input and on Ctrl/Z, displays the prompt message. Again, no output is displayed.

Why is this happening?

Thanks.
cin.ignore(INT_MAX);

You've told it to clear INT_MAX from the buffer. So it will. You're going to have to put INT_MAX into it so it can clear them all. It's sitting there waiting for more input in the buffer to clear.

Alternatively, cin.ignore(INT_MAX, '\n') so it clears INT_MAX or until the next '\n' it encounters.
Last edited on
Instead, in the local program, the program pauses for user input and on Ctrl/Z, displays the prompt message.

Your use of ignore effectively tells cin to ignore all input - hence you found yourself in the awkward situation of having to break out of that state by signalling end of stream. Once the cin end is reached, no further input is possible. (you might find some workaround but I'm not sure how reliable that would be).

The ignore() function properly belongs inside function get0() because that is where the user typed some characters ending with a newline. Consequently that is where you need to ignore until the newline is reached and discarded.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <limits>


using namespace std;

void ignore_until_newline()
{
    std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );    
}

/// test the get(c) stream member function
void get0()
{
    char c;

    cout << "Please type some characters: ";
    cin.get(c);

    // Skip the rest of the buffer.
    ignore_until_newline();    

    cout << "the 1st "
         << " character typed: "
         << c << endl << endl;
}


/// test the get(p, n) stream member function
void get1()
{
    char word[10];
    int n = 5;


    cout << "Please type some characters: " << endl;
    cin.get(word, n);

    cout << "the 1st " << n - 1
         << " characters typed: "
         << word << endl << endl;
}


int main()
{
    get0();    
    get1();
}
After some work, I've got the right solution. It's the alternative posted by Repeater.

My error was the following statement:

 
cin.ignore(INT_MAX);


This actually works out to:

 
cin.ignore(INT_MAX, traits::eof());


Hence, the program waited for me to enter EOF (ie, Ctrl/Z).

The right code is:
 
cin.ignore(INT_MAX, '\n');


Here's the corrected program. I've tested it offline and it works:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>         /// cin, cout
#include <climits>          /// INT_MAX

using namespace std;

/// test the get(c) stream member function
void get0()
{
    char c;

    cout << "Please type some characters: ";
    cin.get(c);

    cout << "the 1st "
         << " character typed: "
         << c << endl << endl;
}


/// test the get(p, n) stream member function
void get1()
{
    char word[10];
    int n = 5;

    /// Skip the rest of the buffer including the newline.
    cin.ignore(INT_MAX, '\n');

    cout << "Please type some characters: ";
    cin.get(word, n);

    cout << "the 1st " << n - 1
         << " characters typed: "
         << word << endl << endl;
}


int main()
{
    get0();
    get1();
}
Not sure that's the right solution.

What happens if you change main() to just:
1
2
3
4
int main()
{
    get1();
}

Last edited on
Topic archived. No new replies allowed.