Saturday, July 15, 2023

Check for int's validation in CPP & it's ".so" file


CValidator Class as shared library :-
----------------------------------------------

first open codeblocks IDE-> new project -> shared library -> next -> C++ :-

1. project title   : validator
2. folder project : /opt/so-file/validator
3. project name   : validator
4. resulting file name : automated by IDE


This "so" file name will be same as name of "project title ".


Now :-
----------
1. remove main.cpp
2. Project -> Build options -> Position Independent Code(-fPIC) -> right tick on it.
3. Have g++ follow the coming C++1y (aka C++14) ISO C++ language standard -> right tick on it.
4. Target x86_64 (64bit) -> right tick on it.

5. add header file validator.h

#ifndef VALIDATOR_H_INCLUDED
#define VALIDATOR_H_INCLUDED

static std::string  sint;

class CValidators
{
private:
//    static std::string  sint;
    int i;
    char ch;

public:
    CValidators();

    static bool intvalidator(std::string sint);
};

#endif // VALIDATOR_H_INCLUDED

6. add source file validator.cpp

#include "validator.h"

#include <iostream>
#include <string>

using std::string;

bool CValidators::intvalidator(string sint)
{
    int i; 

    if(sint.length() == 0)

    { return false; }


    char ch = sint.at(0);
    if(ch == '-')
        i = 1;
    else
        i = 0;
    for(; i < sint.length(); i++)
    {
        ch = sint.at(i);

        if(isdigit(ch) == false)
        {
            return false;
        }
    }
    return true;
}

--------------------------------------------------------------
compile it and build library file as named : libvalidator.so

now call this file in our new project "int-validation" :-

#include <iostream>
#include <string>
#include <validator.h>

using namespace std;

int main()
{

    string str;
    cout << "Enter number : ";
    getline(cin, str);

    bool tf = CValidator::intvalidator(str);

    if(tf == true)
        cout << "Valid integer" << endl;
    else if(tf == false)
        cout << "invalid integer" << endl;


/* now convert it from string to int. Because in place where we get input of int directly, if we give input of non int such as any character, program will crash. So we need to get it as string, which will get input of non ints and program will not crash. then check it via isdigit(char x) in loop, and then convert this string into int after checking of  validation. */


    return 0;
}

/*
output :-
---------

[rahul@C-Client Release]$ ./int-vallidation
Enter number : 123
Valid integer
[rahul@C-Client Release]$ ./int-vallidation
Enter number : 23e4
invalid integer
[rahul@C-Client Release]$ ./int-vallidation
Enter number : 23444r
invalid integer
[rahul@C-Client Release]$ ./int-vallidation
Enter number : e333333
invalid integer
[rahul@C-Client Release]$ ./int-vallidation
Enter number : 232323423234234234234
Valid integer
[rahul@C-Client Release]$
*/

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

to see how to build and call shared library files see mine other blogs, thanks.

Friday, July 14, 2023

building ".so" file i.e. shared library for getch, getche , clrscr & gotoxy, for command prompt ( terminal )

 "clrscr-getch.h" header and shared library file : "libclrscr-getch.so" to getch, getche , clrscr & gotoxy for terminal in C++ in centos 7 linux. :-
-----------------------------------------------------------------------

first open codeblocks IDE-> new project -> shared library -> next -> C++ :-

1. project title   : clrscr-getch
2. folder project : /opt/so-file/clrscr-getch
3. project name   : clrscr-getch
4. resulting file name : automated by IDE
 

This "so" file name will be same as name of "project title ".

Now :-
------

1. remove main.cpp
2. Project -> Build options ->  Position Independent Code(-fPIC) -> right tick on it.
3. Have g++ follow the coming C++1y (aka C++14) ISO C++ language standard -> right tick on it.
4. Target x86_64 (64bit) -> right tick on it.
5. new file :-
important point : do not add new class to this project because if you do this,
resultant "so" file header will not be able to added in calling cpp project, for example if you build a so file as "so-file.so" and header file "so-file.h" to call its functionalities. Now you add this shared object and header files in your "so-file.so" calling CPP project. In place where we add header file via "#include" directive, intellisense does not recognize it's header file here "so-file.h" will not be added.
    To get it recognized, you need to add as this :-
1. new -> file -> C/C++ header -> next ->
   i. file name with full path :- "clrscr-getch.h"
   ii. Header guard will be generated automatically.
   iii. add file to active project : right tick on both Debug and Release
   
2. new -> file -> C/C++ source -> next -> C++ ->
    i. file name with full path : "clrscr-getch.cpp" - be sure name should be same as header file but extension is ".cpp".
    ii. Add file to active project : right tick on both Debug and Release -> finish.
3. project -> properties -> bin/Debug/libclrscr-getch.so
                            bin/Release/libclrscr-getch.so
    here "libclrscr-getch.so" name by default will be "liblibclrscr-getch.so"
    you need to change it to from double "liblib..." to single "lib..."
    as from "liblibclrscr-getch.so" to "libclrscr-getch.so".
    this "so" file name will be same as name of project name. As here mine project name is : "clrscr-getch".
-------------------------------------------------------------------------

Code :-
----------

add header file : "clrscr-getch.h" :-
----------------------------------------

#ifndef CLRSCRGETCH_H_INCLUDED
#define CLRSCRGETCH_H_INCLUDED

#include <iostream>
#include <sys/ioctl.h>
#include <unistd.h>

#include <termios.h>
#include <cstdio>
#include <iomanip>

static struct termios oldterm, newterm;

class CClrscrGetch
{
public:
    CClrscrGetch();
    virtual ~CClrscrGetch();

    void gotoxy(int x, int y);
    void clrscr();
    void clrscr(int x1, int y1, int x2, int y2);


    char getch();
    char getche();

protected:

private:

    void initTermios(bool echo);
    void resetTermios();
    char getch_(bool echo);
};

#endif //CLRSCRGETCH_H_INCLUDED

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

add source File : "clrscr-getch.cpp" :-
--------------------------------------------------------
#include "clrscr-getch.h"
#include <cstdio>


using std::cin;
using std::cout;

CClrscrGetch::CClrscrGetch()
{
    //ctor
}

CClrscrGetch::~CClrscrGetch()
{
    //dtor
}

void CClrscrGetch::gotoxy(int x, int y)
{
    printf("%c[%d;%df", 0x1B, y, x);
}

void CClrscrGetch::initTermios(bool echo)
{
    tcgetattr(0, &oldterm);
    newterm = oldterm;
    newterm.c_lflag &= ~ICANON;
    newterm.c_lflag &= echo ? ECHO : ~ECHO;
    tcsetattr(0, TCSANOW, &newterm);
}

void CClrscrGetch::resetTermios()
{
    tcsetattr(0, TCSANOW, &oldterm);
}

char CClrscrGetch::getch_(bool echo)
{
    char ch;
    initTermios(echo);
    ch = getchar();
    resetTermios();

    return ch;
}

char CClrscrGetch::getch()
{
    char ch = getch_(false);
    return ch;
}

char CClrscrGetch::getche()
{
    char ch = getch_(true);
    return ch;
}

void CClrscrGetch::clrscr()
{
    gotoxy(0, 0);
    struct winsize w;
    ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);

    for( int i = 0; i < w.ws_row; i++)
    {
        for(int j = 0; j < w.ws_col; j++)
        {
            cout << " ";
        }
    }
    gotoxy(0, 0);
}

void CClrscrGetch::clrscr(int x1, int y1, int x2, int y2)
{    

    int k = y1;
    gotoxy(x1, y1);

    for( int i = 0; i < x2; i++)
    {
        for(int j = 0; j < y2; j++)
        {
            cout << " ";
        }

        gotoxy(x1, ++k);
    }
    gotoxy(x1, y1);
}
----------------------------------------------------------
resultant "so" will be generated in folder "Debug" or "Release" with "so" extension.

To get it to include in all projects, this file to be recognized locally (under account of its own user) or globally (for all users account). To do that you can do this :-
    i. add it to local user : gedit -> open -> or "home/<user>/.bash_profile".
        add this : "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:<path to your so file>"
    ii. add it for all users (globally) :
        1. login as root user
        2. gedit -> open -> /etc/profile" and add following (for example) :-
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/so-file/clrscr-getch
 
 here "/opt/so-file/clrscr-getch" is path of shared object file path to shared as globally.
         3. or you can also put in "/usr/lib" or "/usr/lib64/" or "/usr/local/lib/" or "/usr/local/lib64/"
         this will look this file as globally for all applications.
         But may be name clashing happen, so it is convenient to create folder as named "clrscr-getch" then paste shared library. 

        4. For "header file" - "clrscr-getch.h" put this in "/usr/include/clrscr-getch/", or where you are convenient to add header file that is easier to understand or search in your calling project by compiler. As I added here "/opt/so-files/include/headers/".
----------------------------------------------

Now we will call this shared object file in our CPP project :-
--------------------------------------------------------------

1. new -> project -> Console application -> next -> C++ ->
    i. Project title : test-ops
    ii. Folder to create project in : give path to project location
    iii. project name and resultant file name : manage it by self.
    iv. finish.
2. Project -> build options ->     
    i. Have g++ follow the coming C++1y (aka C++14) ISO C++ language standard -> right tick on it.
    ii. Target x86_64 (64bit) -> right tick on it.
3. linker settings : add -> clrscr-getch
    here IDE will add this shared object file as : "-lclrscr-getch"
    you do not need to add full name - with extension.
4. search directories ->
    i. Compiler -> add ->/opt/so-file/clrscr-getch
        path to header file : in my case path of "clrscr-getch.h" .
        you can give here as either absolute or relative path.
    ii. Linker -> add -> /opt/so-file/clrscr-getch
        path to shared object ".so" file :  in may case path of "libclrscr-getch.so"
5. add using include directive of header file :    <clrscr-getch.h>
    if it is not in intellisense "Reparse this project" as : right click on project name and select "Reparse this project". Then try again.

6. While you are in terminal and there is problem of can not find shared library of given name. Then run following command to reload global profile ( /etc/profile) or local profile (~/.bash_profile ) :-

# source /etc/profile ( press enter  )

$ ./test-so ( press enter ) ( mine "so" file test project )
 

// example file : project : test-ops :-
---------------------------------------
#include <iostream>
#include <clrscr-getch.h>

using namespace std;

int main()
{
    cout << "Hello world!" << endl;

    CClrscrGetch *get = new CClrscrGetch;

    get->gotoxy(2, 4);

    cout << "Hello i am here";

    get->getch();

    get->clrscr();

    get->getch();

    get->gotoxy(3, 9);

    cout << "I am Here";

    get->getch();
    get->gotoxy(4, 60);
    cout << "enter char : ";
    char ch = get->getche();

    get->gotoxy(23, 12);

    cout <<"you entered : " << ch;

    get->getch();

    get->clrscr();

    return 0;
}

---------------------------------------------
Now you can add this "clrscr-getch.h" header and shared library file : "libclrscr-getch.so" into different projects and declare an object or pointer to object of class "CClrscrGetch" and initialize it. then using it you can access functions : "gotoxy(int x, int y), clrscr(), clrscr(int x1, int y1, int x2, int  y2) for clearing a rectangle in terminal, getch() and getche()"
  
    NOW THIS IS COMPLETE
------------------------------------------------------------------

Wednesday, July 12, 2023

shared library (".so") file in C++ in Centos 7 Linux

 ".so" file - "shared object file" i.e. "shared library file" creation in C++ in centos 7 linux. :-
----------------------------------------------------------------------------------------------------

before building ".so" library, build your C++ project for that library, so that we can test working of targeted library file. After successfully testing and seeing proper output and functionality checking, build  library. This way is easier than  directly building ".so" file, because we can not test functionality of ".so" lib file in shared library project. It needs runnable program to test. So first test than build library.


first open codeblocks IDE-> new project -> shared library -> next -> C++ :-

1. prject title   : so-file
2. folder project : /opt/projects/so-file
3. project name   : so-file
4. resulting file name : automated by IDE

This "so" file name will be same as name of "project title ".

Now :-
------

1. remove main.cpp
2. Project -> Build options -> tick on Position Independent Code(-fPIC) -> right tick on it.
3. Have g++ follow the coming C++1y (aka C++14) ISO C++ language standard -> right tick on it.
4. Target x86_64 (64bit) -> right tick on it.
5. new file :-
important point : do not add new class to this project because if you do this,
resultant "so" file header will not be able to added in calling cpp project. For example if you build a so file as "so-file.so" and header file "so-file.h" to call its functionalities. Now you add this shared object and header files in your "so-file.so" calling CPP project. In place where we add header file via "#include" directive, intellisense does not recognize it's header file e.g. "so-file.h" will not be added.
    To get it recognized you need to add as this :-
1. new -> file -> C/C++ header -> next ->
   i. file name with full path :- "so-build-w-class.h"
   ii. Header guard will be generated automatically.
   iii. add file to active project : right tick on both Debug and Release
   
2. new -> file -> C/C++ source -> next -> C++ ->
    i. file name with full path : "so-build-w-class.cpp" - be sure name should be same as header file but extension is ".cpp".
    ii. Add file to active project : right tick on both Debug and Release
    -> finish.
3. project -> properties -> bin/Debug/lib01-so-test-h-s.so
                            bin/Release/lib01-so-test-h-s.so
    here "lib01-so-test-h-s.so" name by default will be "liblib01-so-test-h-s.so"
    you need to change it to from double "liblib..." to single "lib..."
    as from "liblib01-so-test-h-s.so" to "lib01-so-test-h-s.so".
    this "so" file name will be same as name of project name. As here mine project name is : "01-so-test-h-s".
-------------------------------------------------------------------------
Example :-
----------

file : "so-build-w-class.h" :-
------------------------------

#ifndef SO-BUILD-W-CLASS_INCLUDED
#define SO-BUILD-W-CLASS_INCLUDED

class print_one
{
public:
    print_one();
    virtual ~print_one();

    void print();
    void read();

protected:

private:

    int i, j;

};

#endif // SO-BUILD-W-CLASS_INCLUDED
---------------------------------------

File : "so-build-w-class.cpp" :-
--------------------------------
#include "so-build-w-class.h"
#include <iostream>

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

print_one::print_one()
{
    //ctor
    i = j = 5;
}

print_one::~print_one()
{
    //dtor
}

void print_one::print()
{
    cout << "i = " << i << endl;
    cout << "j = " << j << endl;
}

void print_one::read()
{
    cout << "i = ";
    cin  >> i;
    cout << "j = ";
    cin  >> j;
}


resultant "so" will be generated in folder "Debug" or "Release" with "so" extension.

To get it to include in all projects, this file to be recognized locally (under account of its own user) or globally (for all users account). To do that you can do this :-
    i. add it to local user : gedit -> open -> or "home/<user>/.bash_profile".
        add this : "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:<path to your so file>"
    ii. add it for all users (globally) :
        1. login as root user
        2. gedit -> open -> /etc/profile" and add following (for example) :-
        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/oracle/instantclient_11_2:/opt/project/lpi/lpi_headers:/opt/so-files:/opt/so-files/so-file-test-without-class/so-files-wc
 
 here "/opt/so-files/so-file-test-without-class/so-files-wc" is path of shared object file path to shared as globally.
         3. or you can also put in "/usr/lib" or "/usr/lib64/" or "/usr/local/lib/" or "/usr/local/lib64/"

        4. or you can make directory "/usr/lib64/your_dir" and paste it your "so" file.


         this will look this file as globally for all applications.
         But may be name clashing happen.
----------------------------------------------

Now we will call this shared object file in our CPP project :-
--------------------------------------------------------------

1. new -> project -> Console application -> next -> C++ ->
    i. Project title : Calling-CPP-project
    ii. Folder to create project in : give path to project location
    iii. project name and resultant file name : manage it by self.
    iv. finish.
2. Project -> build options ->     
    i. Have g++ follow the coming C++1y (aka C++14) ISO C++ language standard -> right tick on it.
    ii. Target x86_64 (64bit) -> right tick on it.
3. linker settings : add -> 01-so-test-h-s
    here IDE will add this shared object file as : "-l01-so-test-h-s"
    you do not need to add full name - with extension.
4. search directories ->
    i. Compiler -> add -> /opt/so-files/so-file-test-without-class/so-files-wc
        path to header file : in may case path of "so-build-w-class.h".
        you can give here as either absolute or relative path.
    ii. Linker -> add -> /opt/so-files/so-file-test-without-class/so-files-wc
        path to shared object ".so" file :  in may case path of "lib01-so-test-h-s.so"
5. add using include directive of header file :    <so-build-w-class.h>
    if it is not in intellisense "Reparse this project" as : right click on project name and select "Reparse this project". Then try again.
 

// example file : project : calling-cpp :-
------------------------------------------
#include <iostream>

#include <so-build-w-class.h>

using namespace std;

int main()
{
    cout << "Hello world!" << endl;

    print_one p;

    p.print();

    cout << "Ente i and j : " << endl;

    p.read();

    cout << endl;

    p.print();

    return 0;
}
 

output :-


[rahul@C-Client Debug]$ ./calling-cpp
Hello world!
i = 5
j = 5
Ente i and j :
i = 3
j = 4

i = 3
j = 4
[rahul@C-Client Debug]$
   
    NOW THIS IS COMPLETE
------------------------------------------------------------------