peek

I/O functions in C++

C++ has two very useful stream functions, peek() and putback(). The peek() function looks into the input stream and tells us what the next character is without removing it from the input stream. Moreover, the peek() function can store the character in a designated memory locatio without actually removing it from the stream. The putback() function lets us put the last character extracted from the input stream by the get() function back into the input stream. We will be using both functions with the input stream object cin.

#include <iostream>

using namespace std;

int main()
{
    char ch, peekCh;
    cout << "Enter a string: ";
    
    cin.get(ch);
    cout << "After first cin.get(ch): ";
    cout << "ch = " << ch << endl;
    
    cin.get(ch);
    cout << "After second cin.get(ch): ";
    cout << "ch = " << ch << endl;
    
    //put the character back in the stream
    cin.putback(ch);
    cin.get(ch);
    cout << "After putback, the third cin.get(ch): ";
    cout << "ch = " << ch << endl;
    
    //get next character in stream
    //without removing it
    peekCh = cin.peek();
    cin.get(ch);
    
    cout << "After peek, the fourth cin.get(ch): ";
    cout << "ch = " << ch << endl;
    cout << "And peekCh = " << peekCh << endl;
    
    return 0;
}

Note that the functions get(), peak(), and putback() are members of the istream data type. They are used with the cin stream object using dot notation, where a dot or period separates the input stream object name from the function name. 

A lot of things can happen during program execution, especially when accepting user input. Programs are vulnerable to input failure, either accidental or even sometimes deliberate. In the event of input failure, the input stream enters into a fail state. Once an input stream enters a fail state, all further I/O statements using that stream are ignored. The results can be bad – very, very bad.

#include <iostream>

using namespace std;

int main()
{
    int a;
    int b = 42;
    //enter a string value
    cout << "Enter an int:\t";
    cin >> a;
    
    //now enter an int (other than 42)
    cout << "Enter another int:\t";
    cin >> b;
    
    cout << "The numbers you entered are: ";
    cout << a << " \t " << b << endl;
    
    return 0;
}

When the input stream enters the fail state, all further I/O using that stream is ignored. We can use the clear() function to restore the input stream to a working state. We use clear() with the cin object using dot notation, as we did with the putback() and peek() functions.

#include <iostream>

using namespace std;

int main()
{
    char c;
    int a = 73;
    
    //enter a multiple digit number
    cout << "Enter a character: \t";
    cin >> c;
    
    //restore the input stream
    cin.ignore();
    
    cout << "Now enter an integer: \t";
    cin >> a;
    
    cout << "You entered: ";
    cout << c << " and " << a;
    
    return 0;
}

Of course, it’s not enough to restore the input stream, we also must clear the input buffer as well. The easiest way to do this is by using the ignore() function.

#include <iostream>
#include <limits>

//important!
#define STREAM_MAX std::numeric_limits<std::streamsize>::max()

using namespace std;

int main()
{
    int a;
    char c;
    double d;
    
    //enter a string instead
    cout << "Enter an integer: ";
    cin >> a;
    
    cin.clear();
    //ingore till newline character
    //or numeric_limits<streamsize> characters
    cin.ignore(STREAM_MAX, '\n');
    
    //enter a number greater than 9
    cout << "Enter a character: ";
    cin >> c;
    
    cin.clear();
    cin.ignore(STREAM_MAX, '\n');
    
    //give correct input for this
    cout << "Enter a decimal number: ";
    cin >> d;
    
    cout << endl << "You entered: " << endl;
    cout << "int a = " << a << endl;
    cout << "char c = " << c << endl;
    cout << "double d = " << d << endl;
    
    return 0;
}

Note that we need to include the limits header file.