3-7) User Input and Output

This section shows how the cin (keyboard) is used to collect user input.


Sample Code


Stream cin, cout, cerr, clog and stream insertion and extraction

A file should only be "seen"  once when code is compiled. Conditional compile preprocessor directives can be used to prevent the compiler from seeing a file more than once -even if it is included several times.
 
 

//file cin_and_cout.cpp
/* The objects cin, cout, cerr, clog and the
stream insertion and stream extraction operators
*/

#include <iostream>
using namespace
std;

void main(){
//cout is ostream object bound to console display
//cin is istream object bound to keyboard
//cerr is unbuffered ostream object (console display)
//clog is buffered ostream object (console display)
 

    //stream insertion operator
    cout << "Please enter your favourite int: ";
    int response = -1;

    //stream extraction operator
    cin >> response;
    cout <<
"\n";
    cout <<
"Favourite Number: " << response << "\n"
;

    cerr << "ERROR" << "\n";
    clog <<
"LOG ENTRY" << "\n"
;

}

/*
Please enter your favourite int: 42
Favourite Number: 42
ERROR
LOG ENTRY
*/


Outputting Strings with operator<<()

//file outputing_strings.cpp
 

/* Outputing Strings and Characters
Notice C++ << operator assumes if you are outputting a char*
that you want to see the string it represents whereas if you
output a int* you want to see the pointer address

(Notice the ugly casting)
*/


#include <iostream>

using namespace std;

void main(){

    int i = 42;
    int* iptr = &i;

    char * greeting = "Hello World";

    cout << iptr << "\n"; //outputs itpr value
    cout << greeting << "\n"; //outputs string
    cout << (void *) greeting << "\n"; //outputs greeting value

    char * cPtr = greeting;
    char c = *cPtr;
    while(c != '\0'){
        cout << c << "\t" << (int) c << "\n";
        //cout.put(c).put('\n'); //alternatively
        cPtr++;
        c = *cPtr;
    }

}

/*
0012FF60
Hello World
00417804
H 72
e 101
l 108
l 108
o 111
32
W 87
o 111
r 114
l 108
d 100
*/


Reading User Input with cin >>

The stream extraction operator may or may not ignore white-space characters depending on what is being read. Using cin >> can be dangerous for gathering user input because of the unpredictable nature of the user's typed responses.

 

//file cin_example1.cpp


/* Notice how >> operator ignores white-space characters between
      stream input, but uses them to terminate strings
*/

 

#include <iostream>
using namespace std;

void main(){

    int i,j,k;

    cout << "Enter three ints (e.g. 42 13 123): ";
    cin >> i;
    cin >> j;
    cin >> k;

    cout << "The ints were: " << i << ", " << j << ", " << k << "\n";


    cout << "Enter your name: ";

    char * response = new char[30]; //dangerous
    cin >> response;

    cout << "Hello " << response << "\n";

    delete [] response;



    //This will keep looping until <ctrl>-z is typed (Windows EOF key sequence)
    //<ctrl>-d on UNIX or Mac
    //Notice how cin >> evaluates to a boolean (C++ type conversion and casting)
    //C++ istream class defines a type conversion rule that converts cin to zero, or a positive
    //integer depending on whether cin has been closed or not.
    //For example, the i/o stream classes may implement a conversion operator as follows
    //
    //     operator void*() const //convert to a void pointers
    //     {return fail() ? NULL : reinterpret_cast<void*>(-1); {

    int anInt;
    cout << "Enter int: ";
    while (cin >> anInt){
        cout << "int: " << anInt << "\n";
        cout << "Enter another int: ";
    }

}


Reading Individual Characters with cin.get()

The cin.get() member function will read individual characters from the input stream including white-space characters
cin.eof() can be used to test whether the stream has reached the end-of-file

 

//file cin_and_get
/* reading individual characters with get()
*/

#include <iostream>
using namespace std;

void main(){

    const int MAX_SIZE = 80;

    int aChar;

    cout << "cin.eof() = " << cin.eof() << "\n";
    cout << "Enter a string followed by <cntr>-z : ";

    while ( (aChar = cin.get() ) != EOF ){ //EOF is defined in <iostream>
        cout.put(aChar);

    }

    cout << "cin.eof() = " << cin.eof() << "\n";
    cout << "clearing input stream \n";
    cin.clear(); //necessary to do the second test
    cout << "cin.eof() = " << cin.eof() << "\n";

    cout << "SECOND TEST \n";

    char someChars[MAX_SIZE];
    int index = 0;

    while ( (aChar = cin.get() ) != EOF ){
        someChars[index++] = aChar;

    }
    someChars[index] = '\0'; //null terminate the string
    cout << "String= " << someChars << "\n";

}


Reading Entire Lines with cin.getline()

The cin.getline() member function will read an entire line up to the '\n' character
This is probably one of the better ways to collect user input so that your program can parse the input string however it wants.

 

//file: cin_and_getline

/* reading entire lines with cin.getline()
getline() will read all the characters up to the default
delimiter of '\n'.
*/

#include <iostream>
using namespace std;

void main(){


    const int MAX_SIZE = 80;
    char buffer[MAX_SIZE];

    cout << "cin.eof() = " << cin.eof() << "\n";
    cout << "What is your name?: ";
    cin.getline(buffer, MAX_SIZE);

    cout << "you said:" << "\n";
    cout << buffer << "\n";

    cout << "What is your favourite number: ";
    cin.getline(buffer, MAX_SIZE);

    cout << "you said:" << "\n";
    cout << buffer << "\n";

}


Obtaining BankAccount info from User

Here the constructor of the BankAccount class prompts the user for initialization information.

 

//file: reading_BankAccount_info.cpp
/* Obtaining contructor information from user
*/

#include <iostream>
using namespace std;

class BankAccount{
private:
    int accountNumber;
    char * owner;

public:
    BankAccount(){
    const int MAX_SIZE = 80;
    char buffer[MAX_SIZE];

    cout << "Please enter new account number: ";
    cin >> accountNumber;
    cin.getline(buffer, MAX_SIZE); //because >> does not remove '\n';

    cout << "\n";
    cout << "Please enter you name: ";
    cin.getline(buffer, MAX_SIZE);

    owner = new char[strlen(buffer) + 1];
    strcpy(owner, buffer);
    }

    ~BankAccount(){delete [] owner; }

    void printOn(ostream & stream) const {
        stream << "#" << accountNumber << " owner: " << owner << "\n";
    }
};
 

ostream & operator<<(ostream & stream, const BankAccount & b){
    b.printOn(stream);
    return stream;

}
 

void main(){

    BankAccount b;
    cout << b;

}


Overloading the Stream Extraction Operator

Just like cout << can be overloaded, so can cin >>

 

//file overloading_stream_extraction.cpp
/* Overloading the stream extraction operator
*/

#include <iostream>
using namespace std;

class BankAccount{
private:
    int accountNumber;
    char * owner;

public:
BankAccount(){
    accountNumber = -1;
    owner = NULL;
}

~BankAccount(){delete [] owner; }

void initializeFromStream(istream & stream){
    const int MAX_SIZE = 80;
    char buffer[MAX_SIZE];

    cout << "Please enter new account number: ";
    stream >> accountNumber;
    stream.getline(buffer, MAX_SIZE); //because >> does not remove '\n';

    cout << "\n";
    cout << "Please enter you name: ";
    stream.getline(buffer, MAX_SIZE);

    owner = new char[strlen(buffer) + 1];
    strcpy(owner, buffer);

}

void printOn(ostream & stream) const {
    if(owner == NULL)
        stream << "#" << accountNumber << " owner: " << "UNKNOWN" << "\n";
    else
        stream << "#" << accountNumber << " owner: " << owner << "\n";
}
};
 

ostream & operator<<(ostream & stream, const BankAccount & b){
    b.printOn(stream);
    return stream;
}

istream & operator>>(istream & stream, BankAccount & b){
    b.initializeFromStream(stream);
    return stream;
}

void main(){

    BankAccount b;
    cout << b;
    cin >> b;
    cout << b;

}