I'm trying to build a simple BIN -> HEX converter using a class, I would like to save it later in a header file for eventual need <.<" .
It kinda works. Kinda because I have some output, but I cannot understand what is happening when it prints X. Why Am I getting those else exceptions ? I should get only 4 bit combinations..
I'm trying to learn. Sorry for eventual stupid code.
#include <iostream>
#include <bitset>
class Hash{
private:
char stringa[150];
int byteCount=0;
public:
//call to get a string
void getStringa(){
char temp_char;
std::cout << "Write a string and press enter to continue" << std::endl;
for(unsigned int i = 0; i < 150; i++){
temp_char = std::cin.get();
if(temp_char == '\n'){
stringa[i] = '\0';
byteCount = i;
break;
}
stringa[i] = temp_char;
}
}
char nibbleToHEX(std::bitset<4> x){
char HEX;
if(x == 0000) return HEX = '0';
else if (x == 0001) return HEX = '1';
else if (x == 0010) return HEX = '2';
else if (x == 0011) return HEX = '3';
else if (x == 0100) return HEX = '4';
else if (x == 0101) return HEX = '5';
else if (x == 0110) return HEX = '6';
else if (x == 0111) return HEX = '7';
else if (x == 1000) return HEX = '8';
else if (x == 1001) return HEX = '9';
else if (x == 1010) return HEX = 'A';
else if (x == 1011) return HEX = 'B';
else if (x == 1100) return HEX = 'C';
else if (x == 1101) return HEX = 'D';
else if (x == 1110) return HEX = 'E';
else if (x == 1111) return HEX = 'F';
else return 'X';
}
//call to encode string to 256 binary digits and then go HEX a nibble at a time
void encodeStringa(){
std::cout << "converting |" << stringa << "| to binary: \n";
char HEXSTRINGA[64];
for(unsigned int i = 0; i < 150; i++){
if(stringa[i] == '\0') break;
std::bitset<4> x(stringa[i]);
std::cout << x;
HEXSTRINGA[i] = nibbleToHEX(x);
}
std::cout << std::endl;
std::cout << "You used " << byteCount << " bytes.\n";
std::cout << "You still have " << 64-byteCount << " bytes." << std::endl;
std::cout << "Converted string in HEX form: " << HEXSTRINGA << std::endl;
}
};
int main() {
Hash BCHAIN;
BCHAIN.getStringa();
BCHAIN.encodeStringa();
return 0;
}
Some test IO is:
**Teststring**
0100010100110100001101000010100111100111
XXBXBXA3XF
X is an error at least for what I am trying to do.. I don't get it why, I would expect random combination of 4 bits for some chars.. because I only have 15 combinations with 4 bits. Not an X ... is an overflow issue?
You can do much simpler by simply combining four subsequent characters into a number:
char const* const digits = "0123456789abcdefg"; // or upper case, if you prefer
for(auto i = x; i < byteCount; i += 4)
// ^: to be considered later!
{
unsigned int n
= (stringa[i + 0] == '1') << 3
| (stringa[i + 1] == '1') << 2
| (stringa[i + 2] == '1') << 1
| (stringa[i + 3] == '1') << 0;
HEXSTRING[pos++] = digits[n];
}
So far I did not consider a letter not being either '0'
or '1'
– leaving this to you!
One thing yet open is the number of input digits not being a multiple of 4!
Well, above I started with some unspecified x
, remember? I'd prefer filling up the lacking digits with leading zeros, i.e. considering e.g. 110011
as 00110011
:
size_t pos = 0;
unsigned int n = 0;
size_t offset = byteCount % 4;
if(offset != 0)
{
size_t o = offset - 1
for(size_t i = 0; i <= o; ++i)
{
n |= (stringa[i] == '1') << (o - i);
}
HEX_STRING[pos++] = digits[n];
}
And now we start above loop at this offset:
for(auto i = offset; i < byteCount; i += 4)
{
// ...
}
For this working correctly you yet need to set the byteCount
appropriately. You do so if the string is shorter than 150 characters. You might set it to 150 before entering the loop – but what, if input string is even longer? You'd get inappropriate results!
You might want to prefer reading into a std::string
instead!
std::string stringa;
std::cin >> stringa;
This will stop reading a string at the first whitespace occurring. You might instead use std::getline
if you want to handle input like 00 11
as well (you'd do so with your current solution, but you do not skip the whitespace).
With either approach you then can use stringa.length()
instead of byteCount
, the latter being dropped entirely.