Author Topic: Demo of using C++ cin ... AND ... C++ class  (Read 26431 times)

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Demo of using C++ cin ... AND ... C++ class
« on: January 27, 2016, 03:35:33 AM »



An often asked student request is regarding the use of cin in C++

So ...

here  is a little demo of using cin in C++


Code: [Select]
// demo_cin.cpp //  // 2016-01-26 @ 19:35 //

// a demo of using C++ cin //

#include <iostream>
#include <sstream> // re. stringstream objects //
#include <string>

using namespace std;



char takeInChr( const string& msg )
{
    cout << msg;
    string reply;
    getline( cin, reply );
    if( reply.size() )
        return reply[0];
    // else ...
    return 0;
}

bool more( const string& text = "" )
{
    char reply = takeInChr( "More " + text + "(y/n) ? " );
    if( reply == 'n' || reply == 'N' )
        return false;
    // else ...
    return true;
}




int main()
{
    string dummy;

    do
    {
        cout << "Enter a char: ";
        char c;
        cin >> c; // extract first char //
        /*
        above, skips over any leading whitespace and reads first (non-whitespace) char entered.
        note: leaves any next char like the  '\n' char still in the cin (in) stream
        */
        cout << "You entered: '" << c << "'\n";

        getline( cin, dummy ); // clean up any stuff and '\n' whitespace left over //
        if( dummy.size() != 0 ) cout << "You also entered '" << dummy << "'\n";
    }
    while( more( "characters " ) ) ;



    do
    {
        cout << "Enter an integer: ";
        int val;
        cin >> val;
        /*
        above, skips over any leading whitespace and expects first non-whitespace entered to be a 0..9 or a + or -
        reads all next 0..9's and stops at first non-0..9
        Note: cin flags are set if good data or bad data encountered.
        Note also: cin leaves all next char like the  '\n' char still in the cin (in) stream
        Thus if you entered -123abc  456
        above and then pressed the Enter key,
        val holds -123 and calling cin.good() would then return true,
        but abc 456 and the '\n' whitespace char would still all be in the cin stream
        */
        if( cin.good() )
        {
            cout << "You entered: '" << val << "'\n";
            getline( cin, dummy ); // 'eat' whitespace '\n' left in cin stream //
            if( dummy.size() != 0 ) cout << "You also entered: '" << dummy << "'\n";
        }
        else
        {
            cin.clear(); // firstly, clear (all) cin error flags //
            getline( cin, dummy );
            cout << "Error! Was expecting a *valid* integer, but '" << dummy << "' was encountered.\n";
        }
    }
    while( more( "integers " ) );


    while( true )
    {
        // Safe data entry ... uses  ... as per the following ...

        cout << "Enter your ID number, a space and then your name(s): ";
        string line;

        // get the whole line into 'line' and 'eat' the '\n' char(s) at the end //
        getline( cin, line );


        istringstream iss( line ); // form 'iss' object from string obj. 'line' //


        // then parse out the data you expect from the iss object ...
        int id;
        string name;
        if( iss >> id && id > 0 ) // accept ONLY positive ID's here //
        {
            string word;
            while( iss >> word )
                name += word + ' ';

            if( name.size() != 0 )
            {
                name.erase( name.size()-1 ) ; // erase last ' ' char added //

                cout << "You entered '" << id << ' ' << name << "'\n";
                if( !more( "lines to parse " ) ) break;
            }
            else
                cout << "You forgot to enter any names ... try again.\n";
        }
        else
            cout << "Error! Was expecting a *valid* positive integer ... followed by name(s).\n"
                 << "Try again ...\n";
    }

}

« Last Edit: February 05, 2016, 06:21:39 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: Demo of using C++ cin ... AND ... C++ class
« Reply #1 on: February 05, 2016, 06:32:34 AM »
Things to note about C++ class, and if you are coding a C++ class ...


If you code a C++ class, the standard (class guarantee) expectation is that
all data members will be constructed, initialed to known pre-defined values.


See examples ...


One ...

Code: [Select]
class PairInt
{
   int a, b; // private in class by default here, since was a 'class' //

public:
   // ctor with default values 0,0 //
   PairInt( int a=0, int b=0 ) : a(a), b(b) {} //

   int get_a() const { return a; }
   int get_b() const { return b; }
} ;


// later ...
PairInt pr1; // call s default ctor //
cout << pr1.get_a(); // prints 0 //


Example two ...

Code: [Select]
class Student
{
public:
   // ctor with default values //
   Student( int i=0, string n="" ) : id(i), name(n) {}

   int get_id() const { return id; }
   string get_name() const { return name; }

private:
   int id;
   string name;
} ;


// later ...
Student s; // calls default ctor //
cout << s.get_id(); // prints 0 //


Example three ... 

Code: [Select]
// if you declare a C++ string ...
string s; // calls default ctor//
// note default is s = "" //
cout << s; // will print nothing //


Example four ( and mostly why I am doing this: 'things to note' )

Code: [Select]
// if you declare a C++ vector

vector< int > v; // calls default ctor
// note, a size=0 v is created //

v.resize(5); // calls resize method
// note now v[0].. v[4] all are created, *each initialed to 0* //

// If you now call v.size();
//*** it would return 5 ***

//if you now call ...
cout << v[4]; // prints 0 //


So ...

Code: [Select]
// if you call ...
vector< vector < int > > matrix; // default size of matrix is 0 //

// then after the above, you call ...
const int rows = 3, cols = 5;
matrix.resize( rows ); // size of matrix is now 3 ...
// and matrix[0] .. matrix[2] are all created, each with size 0 //

// now ... can do this ...
for( size_t i = 0; i < matrix.size(); ++ i )
{
   matrix[i].resize( cols );
}

// NOW ... the whole 3 rows by 5 columns matrix is created with ALL 15 elements initialed to 0 //



Try also, and see the comments in the next three example programs ...

(1)
Code: [Select]
// about_class_1.cpp //  // 2016-02-04 //


#include <iostream>
#include <string>

using namespace std;

// This next class will create for you (at compile time) ...
// 1) a default ctor..
// 2) a default copy ctor
// 3) a default overloaded = (assignment operartor)
// 4) a default destructor

class Student
{
    // recall that these are private (by default here) inside a class //
    string id,
           name;
public:
    // mutators/setters //
    void set_id( const string& i )
    {
        id = i;
    }
    void set_name(const string& n )
    {
        name = n;
    }
    // accessors/getters //
    string get_id() const
    {
        return id;
    }
    string get_name() const
    {
        return name;
    }
} ;


// here ... we define an overload of operator << for above 'Student' objects //
ostream& operator << ( ostream& os, const Student& stud )
{
    return os << stud.get_id() << ", " << stud.get_name();
}


int main()
{
    Student stud, stud2; // call default ctor //
    cout << "stud = '" << stud << "'\n";
   
    stud.set_id( "123_456_789" );
    stud.set_name( "Sam Smith" );
    cout << "stud = '" << stud << "'\n";
   
    stud2 = stud; // call to default assignment //
    cout << "stud2 = '" << stud2 << "'\n";
   
    Student stud3(stud2); // call to default copy ctor... //
    cout << "stud3 = '" << stud2 << "'\n";
   
   
    cout << "Press 'Enter' to continue/exit ... ";
    cin.get();
}


(2)
Code: [Select]
// about_class_2.cpp //  // 2016-02-04 //


#include <iostream>
#include <string>

using namespace std;

// This next class will create for you (at compile time) ...
// 1) a VALUES PASSED IN ctor... (but NO default ctor...)
// 2) a default copy ctor
// 3) a default overloaded = (assignment operartor)
// 4) a default destructor

class Student
{
    // recall that these are private (by default here) inside a class //
    string id,
           name;
public:
    // ctor with values ...
    Student( const string& id, const string name )
    : id(id), name(name) {}
   
    // accessors/getters //
    string get_id() const
    {
        return id;
    }
    string get_name() const
    {
        return name;
    }
} ;


// here ... we define an overload of operator << for above 'Student' objects //
ostream& operator << ( ostream& os, const Student& stud )
{
    return os << stud.get_id() << ", " << stud.get_name();
}


int main()
{
    //Student stud; // HERE, a call to default ctor wiil NOT compile, since now, NO default ctor was created //
    Student stud( "123_456_789", "Sam Smith" );
    cout << "stud = '" << stud << "'\n";
   
    Student stud2 = stud; // OK ... SINCE here is REALLY a call to the default copy ctor... //
    cout << "stud2 = '" << stud2 << "'\n";
   
    Student stud3(stud2); // call to default copy ctor... //
    cout << "stud3 = '" << stud2 << "'\n";
   
   
    cout << "Press 'Enter' to continue/exit ... ";
    cin.get();
}


(3)
Code: [Select]
// about_class_3.cpp //  // 2016-02-04 //


#include <iostream>
#include <string>

using namespace std;

// This next class will create for you (at compile time) ...
// 1) a VALUES PASSED IN ctor... AND it also 'doubles as' the default ctor...
// 2) a default copy ctor
// 3) a default overloaded = (assignment operartor)
// 4) a default destructor

class Student
{
    // recall that these are private (by default here) inside a class //
    string id,
           name;
public:
    // ctor with values ... amd ALSO defaults ... AND using an initilization list in ctor... //
    Student( const string& id = "", const string name = "" )
    : id(id), name(name) {}
   
    // accessors/getters //
    string get_id() const
    {
        return id;
    }
    string get_name() const
    {
        return name;
    }
} ;


// here ... we define an overload of operator << for above 'Student' objects //
ostream& operator << ( ostream& os, const Student& stud )
{
    return os << stud.get_id() << ", " << stud.get_name();
}


int main()
{
    Student stud; // HERE, a call to default ctor wiil NOW compile, since NOW, default ctor IS created //
    cout << "stud = '" << stud << "'\n";
   
    Student stud2( "123_456_789", "Sam Smith" );
    cout << "stud2 = '" << stud2 << "'\n";
   
    Student stud3(stud2); // call to default copy ctor... //
    cout << "stud3 = '" << stud2 << "'\n";
   
   
    cout << "Press 'Enter' to continue/exit ... ";
    cin.get();
}
« Last Edit: February 05, 2016, 07:17:22 AM by David »