C/C++ Practice Questions on User Input Problem 15

This is my series on C/C++ problems for accepting user input in a robust way. The questions of this series start from C programs, and they slowly build and convert to classes, and which further build into inheritance. This is Problem 15 of this series.

Last Reviewed and Updated on June 22, 2017
Posted by Parveen(Hoven),
Aptitude Trainer and Software Developer

Advertisement

User Input - Problem 15

Use the class CConsoleInt that you created in Problem 12, to input two numbers and display their sum. This should help you understand the power of OOPS.

Solution
// include all the headers
#include "conio.h"
#include "limits.h"
#include "errno.h"
#include
<iostream>

class CConsoleBase
{

public:
    // the maximum limit allowed, use a static const
    // initialize here itself
    static const int iMAXCHARS = 12;

protected:
    char m_cBuff [iMAXCHARS + 3 +
    /*take two more so that overflow can be detected*/2];

    char* m_cReturn;

    // add a temporary storage to hold a copy of input string
    // while the cleanup takes place
    char m_cTemp [iMAXCHARS + 3 +
    /*take two more so that overflow can be detected*/2];

    // the length of string entered by the user.
    // this length is required during cleanup when
    // we flush the unwanted characters. so we make it
    // a private member
    int m_iInputLength;

public:
    // constructor
    CConsoleBase ()
    {

        // requirement for _cgets
        m_cBuff [0] = (iMAXCHARS + 2) + 1;

    }

protected:
    // returns success if the user enters a string <= 10 chars
    bool ReadConsoleString ()
    {

        m_cReturn = NULL;

        int iLoopCtr = 0;

        m_cReturn = _cgets (m_cBuff);

        // save length in a variable. Why are we saving it ?
        m_iInputLength = strlen (m_cReturn);

        // save console input on the temp for cleanup
        strcpy (this->m_cTemp, this->m_cReturn);

        // Robust programming-
        // remove unwanted, unread characters from the stream
        do
        {

            m_cReturn = _cgets (m_cBuff);

        }while (0 != m_cReturn [0]);

        // now write back to m_cReturn, the value of m_cTemp
        strcpy (this->m_cReturn, this->m_cTemp);

        return (m_iInputLength <= iMAXCHARS);

    }

};

class CConsoleInt : public CConsoleBase
{

    int m_iIntValue;

public:
    inline bool TakeIntInput ()
    {

        // read console
        bool bRet = ReadConsoleString ();

        if (bRet)
        {

            // validate
            // if the user has not entered a proper string
            // we should say it is an error, we are
            // taking the length = 10 but for 64-bit
            // systems this won't work because
            // INT_MAX could be longer
            if (((('-' == m_cReturn [0])
            ||
            ('+' == m_cReturn [0]))
            &&
            11 < m_iInputLength)
            ||
            ('-' != m_cReturn [0]
            &&
            10 < m_iInputLength)
            ||
            (0 == m_iInputLength)
            )
            {

                bRet = false;

            }

            // now check each digit, do checking
            // so long as iRet != -1
            for (int iLoopCtr = 0;

            iLoopCtr < m_iInputLength
            && bRet; iLoopCtr++)
            {

                // if the user enters a sign,
                // we should ignore it in our
                // validation. our purpose is
                // to check for valid numbers
                if (('-' == m_cReturn [0])
                ||
                ('+' == m_cReturn [0]))
                continue;

                if (!isdigit (m_cReturn [iLoopCtr]))
                {

                    bRet = false;

                }

            }

            if (bRet)
            {

                // now verify if the number is
                // within the range.
                // the range as you can see is
                // INT_MAX. so
                m_iIntValue = atoi (m_cReturn);

                // atoi sets errno to ERANGE
                // if out of range occurs the
                // header errno.h is include
                // at the top for this
                if (ERANGE == errno)
                {

                    bRet = false;

                    _set_errno (0);

                }

            }

        }

        return bRet;

    }

    inline int DisplayIntInput ()
    {

        return this->m_iIntValue;

    }

};

int main ()
{

    CConsoleInt obj;

    printf ("Enter first number in the range %d to %d: ",
    INT_MIN, INT_MAX);

    while(!obj.TakeIntInput ())
    {

        std::cout << "Please re-enter, your input is invalid: ";

    }

    int iFirst = obj.DisplayIntInput ();

    printf ("Enter second number in the range %d to %d: ",
    INT_MIN, INT_MAX);

    while(!obj.TakeIntInput ())
    {

        std::cout << "\nPlease re-enter, your input is invalid: ";

    }

    int iSecond = obj.DisplayIntInput ();

    // overflow is not tested for simplicity
    std::cout << "Sum = " << iFirst + iSecond << std::endl;

    return 0;

}


My C/C++ Videos on Youtube

Here is the complete playlist for video lectures and tutorials for the absolute beginners. The language has been kept simple so that anybody can easily understand them. I have avoided complex jargon in these videos.



Creative Commons License
This Blog Post/Article "C/C++ Practice Questions on User Input Problem 15" by Parveen (Hoven) is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Updated on 2017-06-22.


Advertisement