Skip to content

Instantly share code, notes, and snippets.

@Kylmakalle
Created September 18, 2017 19:25
Show Gist options
  • Save Kylmakalle/40dc046fd971c409f5e98f534b85e51b to your computer and use it in GitHub Desktop.
Save Kylmakalle/40dc046fd971c409f5e98f534b85e51b to your computer and use it in GitHub Desktop.
#include <string>
#include <vector>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <memory.h>
// For blocked reading pressed symbol
int getch(){
struct termios oldt, newt;
char ch;
tcgetattr( STDIN_FILENO, &oldt );
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
ch = getchar();
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
return ch;
}
// Class defines
class MenuPoint;
class MenuItem;
class MenuFunction;
// Classes
class MenuPoint // Abstract class for menu elements
{
protected:
std::string name;
MenuPoint *parent;
void setParent(MenuPoint*);
public:
MenuPoint();
void setName(std::string);
std::string getName();
MenuPoint* getParent();
virtual void action() = 0; // Action method
};
class MenuItem: public MenuPoint // Menu Item class
{
private:
std::string welcome_message;
std::vector<MenuPoint*> points; // Array with menu points
unsigned int pointer; // Graphical pointer of current menu point
public:
MenuItem();
MenuItem(std::string);
void action();
void setWelcomeMessage(std::string);
MenuItem* addItem(std::string); // Add menu item in end of list
MenuFunction* addAction(std::string, void(*)()); // Add menu function in end of list
void addItem(MenuItem*); // Add menu item in end of list
void addAction(MenuFunction*); // Add menu function in end of list
MenuItem* insertItem(unsigned int, std::string); // Insert menu item in position
MenuFunction* insertAction(unsigned int, std::string, void(*)()); // Insert menu function in position
void insertItem(unsigned int, MenuItem*); // Insert menu item in position
void insertAction(unsigned int, MenuFunction*); // Insert menu action in position
MenuPoint* deletePoint(unsigned int); // Delete any point from position
MenuPoint* get(unsigned int); // Get menu element
};
class MenuFunction: public MenuPoint
{
private:
void (*func)(void);
MenuPoint *next_point;
public:
MenuFunction();
MenuFunction(std::string, void(*)());
void action();
void setFunction(void(*)());
void setNextItem(MenuItem*); // Set item that will call after current MenuFunction
void setNextAction(MenuFunction*); // Set action that will call after current MenuFunction
MenuItem* setNextItem(std::string); // Set item that will call after current MenuFunction
MenuFunction* setNextAction(std::string, void(*)()); // Set action that will call after current MenuFunction
};
// Class methods
// MenuPoint methods
MenuPoint::MenuPoint()
{
this->parent=0;
}
void MenuPoint::setParent(MenuPoint* parent)
{
this->parent=parent;
}
void MenuPoint::setName(std::string name)
{
this->name=name;
}
std::string MenuPoint::getName()
{
return this->name;
}
MenuPoint* MenuPoint::getParent()
{
return this->parent;
}
// MenuItem method
MenuItem::MenuItem()
{
this->pointer=0;
this->welcome_message="";
}
MenuItem::MenuItem(std::string name)
{
this->pointer=0;
this->welcome_message="";
this->name=name;
}
void MenuItem::action()
{
// Print cycle
while (true)
{
system("clear"); // Clear screen (only linux)
// Print menu
std::cout<<this->welcome_message<<std::endl;
unsigned int size=this->points.size();
for (unsigned short i=0; i<size; i++)
{
if (this->pointer==i)
std::cout<<"* ";
else
std::cout<<" ";
std::cout<<i+1<<". ";
std::cout<<this->points[i]->getName()<<std::endl;
}
if (this->pointer==this->points.size())
std::cout<<"* ";
else
std::cout<<" ";
std::cout<<this->points.size()+1;
if (this->parent)
std::cout<<". Back";
else
std::cout<<". Exit";
std::cout<<std::endl;
switch (getch())
{
case 10: // Enter
if (this->pointer==this->points.size())
return;
this->points[this->pointer]->action();
break;
case 65: // Up
if (!this->pointer)
this->pointer=this->points.size();
else
this->pointer--;
break;
case 66: // Down
if (this->pointer==this->points.size())
this->pointer=0;
else
this->pointer++;
break;
}
}
}
void MenuItem::setWelcomeMessage(std::string welcome_message)
{
this->welcome_message=welcome_message;
}
MenuItem* MenuItem::addItem(std::string name)
{
MenuItem *item=new MenuItem(name);
item->setParent(this);
this->points.push_back(item);
return item;
}
MenuFunction* MenuItem::addAction(std::string name, void(*func)(void))
{
MenuFunction *mfunc=new MenuFunction();
mfunc->setName(name);
mfunc->setFunction(func);
this->points.push_back(mfunc);
return mfunc;
}
void MenuItem::addItem(MenuItem *item)
{
this->points.push_back(item);
}
void MenuItem::addAction(MenuFunction *mfunc)
{
this->points.push_back(mfunc);
}
MenuItem* MenuItem::insertItem(unsigned int index, std::string name)
{
if (index>this->points.size())
return 0;
MenuItem *item=new MenuItem(name);
this->points.insert(this->points.begin()+index, item);
return item;
}
MenuFunction* MenuItem::insertAction(unsigned int index, std::string name, void(*func)())
{
if (index>this->points.size())
return 0;
MenuFunction *mfunc=new MenuFunction(name, func);
this->points.insert(this->points.begin()+index, mfunc);
return mfunc;
}
void MenuItem::insertItem(unsigned int index, MenuItem* item)
{
if (index>this->points.size())
return;
this->points.insert(this->points.begin()+index, item);
}
void MenuItem::insertAction(unsigned int index, MenuFunction* mfunc)
{
if (index>this->points.size())
return;
this->points.insert(this->points.begin()+index, mfunc);
}
MenuPoint* MenuItem::deletePoint(unsigned int index)
{
MenuPoint *point=this->points[index];
this->points.erase(this->points.begin()+index);
return point;
}
MenuPoint* MenuItem::get(unsigned int index)
{
return this->points[index];
}
// MenuFunction method
MenuFunction::MenuFunction()
{
this->func=0;
this->next_point=0;
}
MenuFunction::MenuFunction(std::string name, void(*func)())
{
this->name=name;
this->func=func;
this->next_point=0;
}
void MenuFunction::action()
{
this->func();
if (this->next_point)
this->next_point->action();
}
void MenuFunction::setFunction(void(*func)())
{
this->func=func;
}
void MenuFunction::setNextItem(MenuItem *item)
{
this->next_point=item;
}
void MenuFunction::setNextAction(MenuFunction *mfunc)
{
this->next_point=mfunc;
}
MenuItem* MenuFunction::setNextItem(std::string name)
{
MenuItem *item=new MenuItem(name);
this->next_point=item;
return item;
}
MenuFunction* MenuFunction::setNextAction(std::string name, void(*func)())
{
MenuFunction *mfunc=new MenuFunction(name, func);
this->next_point=mfunc;
return mfunc;
}
// Help functions
char charToDigit(char c) // Function for convert char to digit
{
if (c>47 && c<58)
return c-48;
else if (c>64 && c<91)
return c-54;
else
return c-86;
}
void printBytes(char* array, unsigned char size) // Function for print bytes array in binary view
{
for (unsigned short i=size; i>0; i--)
for (unsigned char j=8; j>0; j--)
{
if (array[i-1] & ((char)1<<(j-1)))
std::cout<<1;
else
std::cout<<0;
}
}
unsigned int symbolPosition(std::string string, char c) // Function for check char in string
{
unsigned int pos=1;
for (std::string::iterator it=string.begin(); it!=string.end(); it++, pos++)
if (*it==c)
return pos;
return 0;
}
// For integer
template <typename T>
void doItInteger(unsigned int scale, std::string data)
{
T k=1;
T result=0;
bool sign=(data[0]=='-');
for (unsigned short i=data.size(); i>1*sign; i--, k*=scale)
result+=charToDigit(data[i-1])*k*(sign?-1:1);
std::cout<<"In type: "<<result<<"\n";
char *bytes=new char[sizeof(T)];
memcpy(bytes, &result, sizeof(T));
std::cout<<"Bytes: ";
printBytes(bytes, sizeof(T));
std::cout<<"\n";
getch();
}
// For float
template <typename T>
void doItFloat(unsigned int scale, std::string data)
{
T k=0.1;
T result=0;
bool sign=(data[0]=='-');
unsigned short pp=symbolPosition(data, '.');
if (!pp)
pp=data.size()+1;
for (unsigned short i=pp; i<data.size(); i++, k/=scale)
result+=charToDigit(data[i])*k*(sign?-1:1);
k=1;
for (unsigned short i=pp-1; i>1*sign; i--, k*=scale)
result+=charToDigit(data[i-1])*k*(sign?-1:1);
std::cout<<"In type: "<<result<<"\n";
char *bytes=new char[sizeof(T)];
memcpy(bytes, &result, sizeof(T));
std::cout<<"Bytes: ";
printBytes(bytes, sizeof(T));
std::cout<<"\n";
getch();
}
/*
* Main menu
* Choose type:
* 1. Bool = 0
* 2. Char = 1
* 3. Unsigned char = 2
* 4. Short int = 3
* 5. Unsigned short int = 4
* 6. Int = 5
* 7. Unsigned int = 6
* 8. Long int = 7
* 9. Unsigned long int = 8
* 10. Float = 9
* 12. Double = 10
*/
// Global variables
unsigned int scale;
std::string symbols;
std::string data;
unsigned char type;
// Main function
int main(int argc, char* argv[])
{
MenuItem types;
MenuFunction what_a_scale("scale", []()
{
symbols.clear();
// Menu for enter scale
while (true)
{
system("clear");
scale=0;
std::cout<<"What number system do you want to use?\nPlease, enter your response (number system may be from 2 to 36): ";
if (!(std::cin>>scale))
{
std::cin.clear();
while (std::cin.get()!='\n');
continue;
}
if (scale>1 && scale<37)
{
// Add digits
for (unsigned char i=0; i<(scale>10?10:scale); i++)
symbols.push_back(48+i);
// Letters
for (unsigned char i=10; i<scale; i++)
{
symbols.push_back(55+i);
symbols.push_back(87+i);
}
break;
}
}
// Input data
while (true)
{
system("clear");
std::cout<<"Please, enter data: ";
std::cin>>data;
// Check input data
bool p=false; // Point
bool pass=true;
for (std::string::iterator it=data.begin(); it!=data.end(); it++)
if (*it=='-')
{
if (it!=data.begin() || type==0 || type==2 || type==4 || type==6 || type==8)
{
pass=false;
break;
}
}
else if (*it=='.')
{
if (it==data.begin() || it==data.end() || *(it-1)=='-' || type<9 || p)
{
pass=false;
break;
}
else
p=true;
}
else if (!symbolPosition(symbols, *it))
{
pass=false;
break;
}
if (pass)
break;
std::cout<<"\nThis data cannot be converted\n";
getch();
getch();
return;
}
system("clear");
switch (type)
{
case 0:
doItInteger<bool>(scale, data);
break;
case 1:
doItInteger<char>(scale, data);
break;
case 2:
doItInteger<unsigned char>(scale, data);
break;
case 3:
doItInteger<short int>(scale, data);
break;
case 4:
doItInteger<unsigned short int>(scale, data);
break;
case 5:
doItInteger<int>(scale, data);
break;
case 6:
doItInteger<unsigned int>(scale, data);
break;
case 7:
doItInteger<long int>(scale, data);
break;
case 8:
doItInteger<unsigned long int>(scale, data);
break;
case 9:
doItFloat<float>(scale, data);
break;
case 10:
doItFloat<double>(scale, data);
break;
}
getch();
});
types.setWelcomeMessage("Choose prefer type:");
types.addAction("Bool", [](){type=0;})->setNextAction(&what_a_scale);
types.addAction("Char", [](){type=1;})->setNextAction(&what_a_scale);
types.addAction("Unsigned char", [](){type=2;})->setNextAction(&what_a_scale);
types.addAction("Short int", [](){type=3;})->setNextAction(&what_a_scale);
types.addAction("Unsigned short int", [](){type=4;})->setNextAction(&what_a_scale);
types.addAction("Int", [](){type=5;})->setNextAction(&what_a_scale);
types.addAction("Unsigned int", [](){type=6;})->setNextAction(&what_a_scale);
types.addAction("Long int", [](){type=7;})->setNextAction(&what_a_scale);
types.addAction("Unsigned long int", [](){type=8;})->setNextAction(&what_a_scale);
types.addAction("Float", [](){type=9;})->setNextAction(&what_a_scale);
types.addAction("Double", [](){type=10;})->setNextAction(&what_a_scale);
types.action();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment