Sunday, April 26, 2026

range based integer input with validation in C++ CLI

 this is program for get input of integer data, defined within a range. That is you can define range e.g. -100 to +200, or + 3 to +500 or etc. But this range number should be within range of integer min and max limit. In this program class CInOutData encapsulates a protected structure SGetData.
 Which contains values for getting input of data as :-
 
 1. intData : initialized as 0, and contains data entered by user. You can gat it from getter.
 
 2. string message : contains error message.
 
 3. limitL and limitR : minimum and maximum limit that can be accepted by user.
 
 You can use setters and getters for these, I've defined those there.
 
 You have to add three shared libraries, and those code are already posted earlier. 
 
 clrscr-getch : for getch(), clrscr(), getche() and gotoxy(int x, int y).
 str-manip    : for trim a string
 validator    : for validate a int 
 
 program for customized, range based, integer values acception is :-
 
File : InOutData.h :-
---------------------
 
 #ifndef CINOUTDATA_H
#define CINOUTDATA_H

#include <clrscr-getch/clrscr-getch.h>
#include <str-manip/str-manip.h>
#include <validator/validator.h>

#include <string>

#include <sys/ioctl.h>


class CInOutData
{
protected:

    struct SGetData
    {
        int intData = 0;
        std::string message = "";

        int limitL = 0;
        int limitR = 0;
    };

    struct winsize w;

//    SGetData *getd;

    CClrscrGetch *get;

    SGetData *sgdata;

public:
    CInOutData();
    virtual ~CInOutData();
    CInOutData(const CInOutData& other);
    CInOutData& operator=(const CInOutData& other);

    bool getInputInt(const int xcoord, const int ycoord, CInOutData *getIOData = nullptr);

    /* setters and getters */

    void setSGDObj(SGetData &);
    SGetData getSGDObj() const;

    void setSGDInData(int);
    int  getSGDInData() const;

    void setSGDMessage(std::string);
    std::string getSGDMessage() const;

    void setSGDLimitL(int);
    int  getSGDLimitL() const;

    void setSGDLimitR(int);
    int  getSGDLimitR() const;



private:
};

#endif // CINOUTDATA_H

-------------------------------------------------------------------------

File : InOutData.cpp :-
-----------------------

#include "InOutData.h"

#include <iostream>

using std::cin;
using std::cout;
using std::endl;
using std::string;

CInOutData::CInOutData()
{
    //ctor

    get     = new CClrscrGetch;
    sgdata  = new SGetData;
}

CInOutData::~CInOutData()
{
    //dtor

    delete get;
    delete sgdata;
}

CInOutData::CInOutData(const CInOutData& other)
{
    //copy ctor
}

CInOutData& CInOutData::operator=(const CInOutData& rhs)
{
    if (this == &rhs) return *this; // handle self assignment
    //assignment operator
    return *this;
}

void CInOutData::setSGDObj(SGetData &inSGetData)
{
        this->sgdata->intData = inSGetData.intData;
        this->sgdata->message = inSGetData.message;
        this->sgdata->limitL  = inSGetData.limitL;
        this->sgdata->limitR  = inSGetData.limitR;
}

void CInOutData::setSGDInData(int inData)
{
    this->sgdata->intData = inData;
}

int  CInOutData::getSGDInData() const
{
    return this->sgdata->intData;
}

void CInOutData::setSGDMessage(std::string inMassage)
{
    this->sgdata->message = inMassage;
}

std::string CInOutData::getSGDMessage() const
{
    return this->sgdata->message;
}

void CInOutData::setSGDLimitL(int inLimitL)
{
    this->sgdata->limitL = inLimitL;
}

int  CInOutData::getSGDLimitL() const
{
    return this->sgdata->limitL;
}

void CInOutData::setSGDLimitR(int inLimitR)
{
    this->sgdata->limitR = inLimitR;
}

int  CInOutData::getSGDLimitR() const
{
    return this->sgdata->limitR;
}

bool CInOutData::getInputInt(const int xcoord, const int ycoord, CInOutData *getIOData)
{


    int i = 0;
    int disp = xcoord;
    int lmt = 0;
    int gdabsL;
    int gdabsR;
    int RoL;
    int ypos = 4;
    int leftlen = 0;
    int rightlen = 0;

    bool tf;

    char key;

    string stringkeys;
    stringkeys.clear();

    if(getIOData == nullptr)
    {
        return false;
    }

/// backspace = 127, Enter = 10, Esc = 27, First int processing for getdata


    if(getIOData->getSGDLimitL() >= getIOData->getSGDLimitR())
    {
        getIOData->setSGDMessage("Left (or Lower) limit is not less than Right (or Greater) limit");
        return false;
    }

    while(true)
    {
        get->gotoxy(xcoord + i, ycoord);
        key = get->getche();

        stringkeys += key;
        i++;

        tf = CString::trimString(&stringkeys);

        if(tf == false)
        {
            --i;
            get->gotoxy(xcoord + i, ycoord);

            continue;
        }

        if(tf == true && key == ' ')
        {
            int len = stringkeys.length();
            get->gotoxy(xcoord + len, ycoord);
            --i;

            continue;
        }

        if( int(key) == 127 )/// int of backspace = 127
        {
            stringkeys.pop_back();

            if(stringkeys == "-")
            {
                stringkeys.clear();

                get->gotoxy(xcoord, ycoord);

                cout << " ";

                i = 0;

                continue;
            }

            if( stringkeys.length() > 0)
            {
                if(stringkeys.length() == 2 && (stringkeys.at(0) == '-' || stringkeys.at(0) == '+'))
                {
                    stringkeys.pop_back();
                    stringkeys.pop_back();

                    get->gotoxy(xcoord, ycoord);
                    cout << "  ";
                    get->gotoxy(xcoord, ycoord);
                    i = 0;

                    continue;
                }

                stringkeys.pop_back();

                i -= 2;
                if( i <= 0 )
                {
                    i = 0;
                }

                get->gotoxy(xcoord + i, ycoord);
                cout << " ";
                get->gotoxy(xcoord + i, ycoord);
            }
            else
            {
                i = 0;
                get->gotoxy(xcoord, ycoord);
            }

            continue;
        }

        gdabsL = std::abs(getIOData->getSGDLimitL());
        gdabsR = std::abs(getIOData->getSGDLimitR());

        string strgdabsL = std::to_string(gdabsL);
        string strgdabsR = std::to_string(gdabsR);

        int lensgdL = strgdabsL.length();
        int lensgdR = strgdabsR.length();

        if(getIOData->getSGDLimitL() < 0 || stringkeys.at(0) == '-' || stringkeys.at(0) == '+')
        {
            lensgdL++;
        }
        else if(getIOData->getSGDLimitR() < 0 || stringkeys.at(0) == '-' || stringkeys.at(0) == '+')
        {
            lensgdR++;
        }

        RoL = (lensgdL < lensgdR) ? lensgdR : lensgdL;

        if( stringkeys.length() > RoL && int(key) != 10 )
        {
            int len = stringkeys.length();
            get->gotoxy(xcoord + len - 1, ycoord);

            cout << " ";
            get->gotoxy(xcoord + len, ycoord);
            stringkeys.pop_back();
            --i;

            continue;
        }

        if(int(key) == 10) /// Enter key = 10 pressed
        {
            stringkeys.pop_back();

            tf = CValidator::intvalidator(stringkeys);

            if (tf == true)
            {
                lmt = std::stoi(stringkeys);

                if(lmt < getIOData->getSGDLimitL() || lmt > getIOData->getSGDLimitR())
                {
                    stringkeys.clear();
                    getIOData->setSGDMessage("outside of range");

                    return false;
                }
                else
                {
                    getIOData->setSGDInData(std::stoi(stringkeys));

                    return true;
                }
            }

            if(tf == false)
            {
                i = 0;
                get->gotoxy(xcoord + stringkeys.length(), ycoord);

                getIOData->setSGDMessage("invalid input");

                stringkeys.clear();

                return false;
            }
        }
    }

    return true;

}

No comments:

Post a Comment