What's new

C/C++ Bits'N'Bytes

B1TW153

B1TW153

Badgerwise?:O
Messages
716
Reaction score
367
Points
260
Sin$
0
I randomly made this for a friend, since he didn't really understand the concept. I'm posting it here today to see if anyone can tell me how I could do it better.

If you want to look at the app;
https://www.virustotal.com/en/file/...fd55458f1b4183d8d4e76ab2a29d5d87265/analysis/

Code:
#include "stdafx.h"
#include <iostream>
#include<Windows.h>
#include<LMCons.h>
#include <typeinfo>
using namespace std;
namespace App
{
   short result; int bytes;
   char*az[] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
   char*thing[] = { "char","int","short","long","long long","float","double","boolean", "char*" };
   enum : int { CHAR, INT, SHORT, LONG, LONG_LONG, FLOAT, DOUBLE, BOOLEAN, STRING };
}

void printInfo(char*data = App::thing[App::result-1])
{
   if(!stricmp(data,App::thing[App::CHAR])) App::bytes = sizeof(char);
   if(!stricmp(data,App::thing[App::INT])) App::bytes = sizeof(int);
   if(!stricmp(data,App::thing[App::SHORT])) App::bytes = sizeof(short);
   if(!stricmp(data,App::thing[App::LONG])) App::bytes = sizeof(long);
   if(!stricmp(data,App::thing[App::LONG_LONG])) App::bytes = sizeof(__int64);
   if(!stricmp(data,App::thing[App::FLOAT])) App::bytes = sizeof(float);
   if(!stricmp(data,App::thing[App::DOUBLE])) App::bytes = sizeof(double);
   if(!stricmp(data,App::thing[App::BOOLEAN])) App::bytes = sizeof(bool);
   if(!stricmp(data,App::thing[App::STRING])) App::bytes = sizeof(char*);
   cout << App::bytes << "Bytes are in a " << App::thing[App::result-1] << endl << App::bytes * 8 << "Bits are in a " << App::thing[App::result-1];
}

void Main()
{
   cout << "#Bitwise  WARNING: Only enter integers!" << endl << endl;
   cout << "1. Char\n2. Int\n3. Short\n4. Long\n5. Long Long\n6. Float\n7. Double\n8. Boolean\n9. String" << endl;
   cout << "Select your option [1-9]; > ";
   cin >> App::result;
   if(App::result <= 9 && App::result > 0 && !strcmp(typeid(App::result).name(), "short")){
   cin.ignore();
   system("cls");
   cout << "You selected " << App::thing[App::result-1] << endl;
   cout << "\n\tGenerating Information on " << App::thing[App::result-1] << "..." << endl;
   Sleep(2000);
   printInfo();
   cin.get();
   system("cls");
   Main();}
   else
     cout << "Wrong option Selected!" << endl;
     Sleep(260);
     system("cls");
     App::result &= ~App::result;
     Main();
}

int _tmain(int argc, _TCHAR* argv[])
{
   SetConsoleTitle(L"\tBits'N'Bytes");
   Main();
}
 
Last edited:
Z61

Z61

Some times our saints are sinners
Retired
Programmer Forum Addict Odysseus' Summit
Messages
5,468
Reaction score
3,429
Points
1,042
Sin$
0
I was going to, but couldn't be bothered tbh. I thought including the source would mean I wouldn't have to anyway, but kthx
It's just a precaution that every file given to users needs to contain a virus scan. I'm sure you can understand why.
 
Jakes625

Jakes625

Enthusiast
Messages
58
Reaction score
21
Points
55
Sin$
7
I randomly made this for a friend, since he didn't really understand the concept. I'm posting it here today to see if anyone can tell me how I could do it better.

If you want to look at the app;
https://www.virustotal.com/en/file/...fd55458f1b4183d8d4e76ab2a29d5d87265/analysis/

Code:
#include "stdafx.h"
#include <iostream>
#include<Windows.h>
#include<LMCons.h>
#include <typeinfo>
using namespace std;
namespace App
{
   short result; int bytes;
   char*az[] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
   char*thing[] = { "char","int","short","long","long long","float","double","boolean", "char*" };
   enum : int { CHAR, INT, SHORT, LONG, LONG_LONG, FLOAT, DOUBLE, BOOLEAN, STRING };
}

void printInfo(char*data = App::thing[App::result-1])
{
   if(!stricmp(data,App::thing[App::CHAR])) App::bytes = sizeof(char);
   if(!stricmp(data,App::thing[App::INT])) App::bytes = sizeof(int);
   if(!stricmp(data,App::thing[App::SHORT])) App::bytes = sizeof(short);
   if(!stricmp(data,App::thing[App::LONG])) App::bytes = sizeof(long);
   if(!stricmp(data,App::thing[App::LONG_LONG])) App::bytes = sizeof(__int64);
   if(!stricmp(data,App::thing[App::FLOAT])) App::bytes = sizeof(float);
   if(!stricmp(data,App::thing[App::DOUBLE])) App::bytes = sizeof(double);
   if(!stricmp(data,App::thing[App::BOOLEAN])) App::bytes = sizeof(bool);
   if(!stricmp(data,App::thing[App::STRING])) App::bytes = sizeof(char*);
   cout << App::bytes << "Bytes are in a " << App::thing[App::result-1] << endl << App::bytes * 8 << "Bits are in a " << App::thing[App::result-1];
}

void Main()
{
   cout << "#Bitwise  WARNING: Only enter integers!" << endl << endl;
   cout << "1. Char\n2. Int\n3. Short\n4. Long\n5. Long Long\n6. Float\n7. Double\n8. Boolean\n9. String" << endl;
   cout << "Select your option [1-9]; > ";
   cin >> App::result;
   if(App::result <= 9 && App::result > 0 && !strcmp(typeid(App::result).name(), "short")){
   cin.ignore();
   system("cls");
   cout << "You selected " << App::thing[App::result-1] << endl;
   cout << "\n\tGenerating Information on " << App::thing[App::result-1] << "..." << endl;
   Sleep(2000);
   printInfo();
   cin.get();
   system("cls");
   Main();}
   else
     cout << "Wrong option Selected!" << endl;
     Sleep(260);
     system("cls");
     App::result &= ~App::result;
     Main();
}

int _tmain(int argc, _TCHAR* argv[])
{
   SetConsoleTitle(L"\tBits'N'Bytes");
   Main();
}

personally I would just add bits to an int (speed purposes) and then just cast / convert to other data types.

ie:
Code:
typedef unsigned short int u16;
typedef unsigned long int u32;
typedef unsigned long long int u64;

main(int argc, char** args)
{
    char* bits = "10101010101"; //get input 'bits'
   
    //set default values for loading value
    u64 value = 0;
    u32 index = 0;
    u32 len = strlen( bits );
   
    //load bits as a 64bit integer (unsigned)
    while( *bits != 0 )
    {
        value |= ((*bits - '0') << (len - index - 1)); //assuming ASCII
        bits++;
        index++;
    }
   
    //convert to various datatypes
    printf( "u64 int: %llu\n", value );                //long long int
    printf( "u32 int: %lu\n", (u32)value );            //int
    printf( "u16 int: %hu\n", (u16)value );            //short int
    printf( "byte: %X\n", (unsigned char)value );    //char
    /* you get the idea... */
   
    return 0;
}
 
AceInfinity

AceInfinity

Enthusiast
Messages
146
Reaction score
39
Points
85
Sin$
0
personally I would just add bits to an int (speed purposes) and then just cast / convert to other data types.

ie:
Code:
typedef unsigned short int u16;
typedef unsigned long int u32;
typedef unsigned long long int u64;

main(int argc, char** args)
{
    char* bits = "10101010101"; //get input 'bits'
   
    //set default values for loading value
    u64 value = 0;
    u32 index = 0;
    u32 len = strlen( bits );
   
    //load bits as a 64bit integer (unsigned)
    while( *bits != 0 )
    {
        value |= ((*bits - '0') << (len - index - 1)); //assuming ASCII
        bits++;
        index++;
    }
   
    //convert to various datatypes
    printf( "u64 int: %llu\n", value );                //long long int
    printf( "u32 int: %lu\n", (u32)value );            //int
    printf( "u16 int: %hu\n", (u16)value );            //short int
    printf( "byte: %X\n", (unsigned char)value );    //char
    /* you get the idea... */
   
    return 0;
}

An int is not going to have enough bits to represent all datatypes. Although if you wanted to do something like that why not use a bitset?

I would suggest using the CHAR_BIT macro though, and to avoid the system() calls. Sleep() is not necessary here either IMO, no need to be fancy with wait times; it's less fancy IMO. I would also recommend that you not introduce recursion here by calling Main() within Main(), that's not good.

I would do something like this:
Code:
#include <iostream>
#include <iomanip>
#include <typeinfo>
#include <typeindex>
#include <algorithm>
#include <climits>
#include <unordered_map>

template <class T>
class type_descriptor
{
public:
  type_descriptor(T val) : _value(val)
  {
    _type_map[typeid(unsigned char)] = "Integer";
    _type_map[typeid(char)] = "Integer";
    _type_map[typeid(unsigned int)] = "Integer";
    _type_map[typeid(int)] = "Integer";
    _type_map[typeid(unsigned long)] = "Integer";
    _type_map[typeid(long)] = "Integer";
    _type_map[typeid(unsigned long long)] = "Integer";
    _type_map[typeid(long long)] = "Integer";
    _type_map[typeid(float)] = "Single Floating Point";
    _type_map[typeid(double)] = "Double Floating Point";

    _type_names['h'] = "unsigned char";
    _type_names['c'] = "char";
    _type_names['j'] = "unsigned int";
    _type_names['i'] = "int";
    _type_names['m'] = "unsigned long";
    _type_names['l'] = "long";
    _type_names['y'] = "unsigned long long";
    _type_names['x'] = "long long";
    _type_names['f'] = "float";
    _type_names['d'] = "double";

  }
  void operator ()() { get_info(_value); }
protected:
  size_t get_bytes(T val) { return sizeof(val); }
  size_t get_bits(T val)  { return get_bytes(val) * CHAR_BIT; }
private:
  void get_info(T val)
  {
    const size_t w = 15;
    std::cout << std::setw(w) << "Type Name: " << _type_names[typeid(val).name()[0]] << '\n';
    std::cout << std::setw(w) << "Type Category: " <<  _type_map[typeid(T)] << '\n';
    std::cout << std::setw(w) << "Min Value: " << (int)std::numeric_limits<T>::min() << '\n';
    std::cout << std::setw(w) << "Max Value: " << (int)std::numeric_limits<T>::max() << '\n';
    std::cout << std::setw(w) << "Bits: " << get_bits(val) << '\n';
    std::cout << std::setw(w) << "Bytes: " << get_bytes(val);
    std::endl(std::cout);
  }
  std::unordered_map<std::type_index, std::string> _type_map;
  std::unordered_map<char, std::string> _type_names;
  T _value;
};

int main()
{
  int value = 30;
  (type_descriptor<int>(value))();
  std::endl(std::cout);
}

The only issue here is with the typeid name() calls, which aren't guaranteed to be the same depending on a few factors, which is stupid IMO. It would almost be better to just determine these things manually. Templates could be used here effectively.

BOOST has a great set of utilities for datatype information as well.
 
Last edited:
Jakes625

Jakes625

Enthusiast
Messages
58
Reaction score
21
Points
55
Sin$
7
An int is not going to have enough bits to represent all datatypes. Although if you wanted to do something like that why not use a bitset?

I would suggest using the CHAR_BIT macro though, and to avoid the system() calls. Sleep() is not necessary here either IMO, no need to be fancy with wait times; it's less fancy IMO. I would also recommend that you not introduce recursion here by calling Main() within Main(), that's not good.

I would do something like this:
Code:
#include <iostream>
#include <iomanip>
#include <typeinfo>
#include <typeindex>
#include <algorithm>
#include <climits>
#include <unordered_map>

template <class T>
class type_descriptor
{
public:
  type_descriptor(T val) : _value(val)
  {
    _type_map[typeid(unsigned char)] = "Integer";
    _type_map[typeid(char)] = "Integer";
    _type_map[typeid(unsigned int)] = "Integer";
    _type_map[typeid(int)] = "Integer";
    _type_map[typeid(unsigned long)] = "Integer";
    _type_map[typeid(long)] = "Integer";
    _type_map[typeid(unsigned long long)] = "Integer";
    _type_map[typeid(long long)] = "Integer";
    _type_map[typeid(float)] = "Single Floating Point";
    _type_map[typeid(double)] = "Double Floating Point";

    _type_names['h'] = "unsigned char";
    _type_names['c'] = "char";
    _type_names['j'] = "unsigned int";
    _type_names['i'] = "int";
    _type_names['m'] = "unsigned long";
    _type_names['l'] = "long";
    _type_names['y'] = "unsigned long long";
    _type_names['x'] = "long long";
    _type_names['f'] = "float";
    _type_names['d'] = "double";

  }
  void operator ()() { get_info(_value); }
protected:
  size_t get_bytes(T val) { return sizeof(val); }
  size_t get_bits(T val)  { return get_bytes(val) * CHAR_BIT; }
private:
  void get_info(T val)
  {
    const size_t w = 15;
    std::cout << std::setw(w) << "Type Name: " << _type_names[typeid(val).name()[0]] << '\n';
    std::cout << std::setw(w) << "Type Category: " <<  _type_map[typeid(T)] << '\n';
    std::cout << std::setw(w) << "Min Value: " << (int)std::numeric_limits<T>::min() << '\n';
    std::cout << std::setw(w) << "Max Value: " << (int)std::numeric_limits<T>::max() << '\n';
    std::cout << std::setw(w) << "Bits: " << get_bits(val) << '\n';
    std::cout << std::setw(w) << "Bytes: " << get_bytes(val);
    std::endl(std::cout);
  }
  std::unordered_map<std::type_index, std::string> _type_map;
  std::unordered_map<char, std::string> _type_names;
  T _value;
};

int main()
{
  int value = 30;
  (type_descriptor<int>(value))();
  std::endl(std::cout);
}

The only issue here is with the typeid name() calls, which aren't guaranteed to be the same depending on a few factors, which is stupid IMO. It would almost be better to just determine these things manually. Templates could be used here effectively.

BOOST has a great set of utilities for datatype information as well.

I didn't use wait, system, or any of the other stuff?

I wouldn't recommend BOOST because it's a huge library for performing a small task.

and a 64bit integer can hold all data types.
 
AceInfinity

AceInfinity

Enthusiast
Messages
146
Reaction score
39
Points
85
Sin$
0
I didn't use wait, system, or any of the other stuff?

I wouldn't recommend BOOST because it's a huge library for performing a small task.

and a 64bit integer can hold all data types.
I never said you did. OP is.BOOST is fine because I dont think you see how much work is involved for a clean portable solution defining all types reliably. Plus, you could expand this program to show more info than just bits and bytes like in my example. I didnt look at your code entirely, my fault. I thought you were using that string at first to construct an integer and that is by no means 64 bits.
 
Jakes625

Jakes625

Enthusiast
Messages
58
Reaction score
21
Points
55
Sin$
7
I never said you did. OP is.BOOST is fine because I dont think you see how much work is involved for a clean portable solution defining all types reliably. Plus, you could expand this program to show more info than just bits and bytes like in my example. I didnt look at your code entirely, my fault. I thought you were using that string at first to construct an integer and that is by no means 64 bits.

Yeah, obviously if you wanted to go more in depth with each type a better library would be more suitable.

For this simple task I think my code would suffice.
 
Top Bottom
Login
Register