How to convert string of binary values back to char
Solution 1
Assuming you want to start at ASCII code 64, and that 'a'
(or 'A'
) is simply 000001
in that case, then you can simply do
c1 = static_cast<char>(std::bitset<6>(arr[0]).to_ulong() + 64); //
'A'
in decimal is 65
, in binary is 0b01000001
. 'a'
in decimal is 97
, in binary is 0b01100001
. In your code, you use a bitset<6>
to store 'a'
(or 'A'
). A bitset<6>
can only represent 2^6
symbols, i.e. 64
, so you will encounter cutting. Basically the 2
most significant bits will be cut. In this case, bitset<6>('A')
becomes 0b000001
, i.e. 1
in decimal, and bitset<6>('a')
becomes 0b1000001
, i.e. 33
in decimal. You can now convince yourself that adding back 64
produces the right result.
EDIT
Note that you can also use std::stoi
(C++11 only) to convert the bit string from base 2 to decimal, as mentioned in the other answers:
char c1 = static_cast<char>(std::stoi(arr[0], nullptr, 2) + 64);
Solution 2
Since you stated you no longer need the std::bitset
after you convert from binary back to your char
representation, you can avoid using it for the conversion.
static_cast<char>(std::stoi(arr[i],0,2) + 64);
Interprets the original binary representation as a base 2 (binary) number and adds 64. Since you have the original char
s stored in a binary format in the arr
array, you can pass them to std::stoi
and specify that the values are base 2, in the 3rd parameter. std::stoi
requires 3 parameters: the string you're trying to convert, a pointer to an int that will store the index of the first unconverted character (unneeded here,so can be left as 0
), and the base of the string argument. Here's more info on that. The result of the std::stoi
call is the base 10 (decimal) equivalent of the binary values. vsoftco's answer explains why adding 64 is the appropriate operation to do here after getting a decimal representation. The result of this is given back as a char
.
If you can afford to use a larger std::bitset
you can even scrap adding 64.
Here's a live demo:
Solution 3
consider the following:
std::cout << "abc" << std::endl;
std::cout << 'a' << 'b' << 'c' << std::endl;
std::cout << std::dec
<< static_cast<int>('a') << " "
<< static_cast<int>('b') << " "
<< static_cast<int>('c') << " "<< std::endl;
std::cout << std::hex
<< static_cast<int>('a') << " "
<< static_cast<int>('b') << " "
<< static_cast<int>('c') << " "<< std::endl;
with output
abc
abc
97 98 99
61 62 63
This shows that each char is binary, and 97 dec is 0x61 hex.
Conversion (to / from binary via bitset) is not necessary.
(or perhaps I am not understanding why you want to do nothing in a somewhat complicated fashion).
Note that static_cast<> causes no code gen. Note that std::dec and std::hex do no change to the data, just to the radix.
edit --- For only 8 bits, you might consider this ... no endian issues.
std::cout << ((('a' >> 7) & 1) ? '1' : '0')
<< ((('a' >> 6) & 1) ? '1' : '0')
<< ((('a' >> 5) & 1) ? '1' : '0')
<< ((('a' >> 4) & 1) ? '1' : '0')
<< ((('a' >> 3) & 1) ? '1' : '0')
<< ((('a' >> 2) & 1) ? '1' : '0')
<< ((('a' >> 1) & 1) ? '1' : '0')
<< ((('a' >> 0) & 1) ? '1' : '0') << " "
<< ((('b' >> 7) & 1) ? '1' : '0')
<< ((('b' >> 6) & 1) ? '1' : '0')
<< ((('b' >> 5) & 1) ? '1' : '0')
<< ((('b' >> 4) & 1) ? '1' : '0')
<< ((('b' >> 3) & 1) ? '1' : '0')
<< ((('b' >> 2) & 1) ? '1' : '0')
<< ((('b' >> 1) & 1) ? '1' : '0')
<< ((('b' >> 0) & 1) ? '1' : '0') << " "
<< ((('c' >> 7) & 1) ? '1' : '0')
<< ((('c' >> 6) & 1) ? '1' : '0')
<< ((('c' >> 5) & 1) ? '1' : '0')
<< ((('c' >> 4) & 1) ? '1' : '0')
<< ((('c' >> 3) & 1) ? '1' : '0')
<< ((('c' >> 2) & 1) ? '1' : '0')
<< ((('c' >> 1) & 1) ? '1' : '0')
<< ((('c' >> 0) & 1) ? '1' : '0') << " "
<< std::endl;
std::cout << std::dec << std::endl;
// with variable
char zulu = 'A';
std::cout << std::dec
<< "NOTE: in this cout, every use of zulu is a 'read' \n"
<< " zulu: " << zulu << " \n"
<< " dec : " << std::dec << static_cast<int>(zulu) << " \n"
<< " --- : " << zulu << " \n" // zulu not changed
<< " hex : " << std::hex << static_cast<int>(zulu) << " \n"
<< " --- : " << zulu << " \n" // zulu not changed
<< " bin : "
<< (((zulu >> 7) & 1) ? '1' : '0')
<< (((zulu >> 6) & 1) ? '1' : '0')
<< (((zulu >> 5) & 1) ? '1' : '0')
<< (((zulu >> 4) & 1) ? '1' : '0')
<< (((zulu >> 3) & 1) ? '1' : '0')
<< (((zulu >> 2) & 1) ? '1' : '0')
<< (((zulu >> 1) & 1) ? '1' : '0')
<< (((zulu >> 0) & 1) ? '1' : '0') << " \n"
<< " --- : " << zulu << " \n" // zulu not changed
<< " bitset: " << std::bitset<8>(zulu) << " \n"
<< " zulu: " << zulu << " \n\nzulu not changed!" // zulu not changed
<< std::endl;
George
Updated on July 26, 2022Comments
-
George almost 2 years
Example
NOTE: that i am only concerned about letters. so bitset 000001 would be
a
orA
.I have a
string
nameds
with the value"abc"
. I take eachchar
of thestring
and convert it to binary value through the use ofbitset
.e.g
bitset <6> b1 = s[0]; //a bitset <6> b2 = s[1]; //b bitset <6> b3 = s[2]; //c
then i want to put the results into an
array
ofstrings
. The name of the array isarr
(and eachstring
of thearray
will represent the binary value of eachchar
)e.g
arr[0] //will hold the value of char 'a' in binary form which is 000001 arr[1] //will hold the value of char 'b' in binary form which is 000010 arr[2] //will hold the value of char 'c' in binary form which is 000011
and the way i convert each
char
from thestring
to binary isarr[0] = b1.to_string(); //arr[0] is now 000001 arr[1] = b2.to_string(); //arr[1] is now 000010 arr[2] = b3.to_string(); //arr[2] is now 000011
Now here lies my problem. How do i convert them back to
char
?e.g.
//I want each char to take back the each corresponding letter from the binary values char c1; //How do i make the arr[0] value of 000001 to become 'a' again? char c2; //Same here char c3; //And here
-
2785528 almost 9 yearsA common question, sure you could not find it?
-
Alejandro almost 9 yearsIf you already have a string representation of the binary value and want to go back to
char
, why not just remove thebitset
middleman and do something likestatic_cast<char>(std::stoi(arr[i]) + 64)
? Then again, I don't know if you need thebitset
for further operations later in your code -
George almost 9 yearsThanks. No i don't need it for anything further. Would that work then without bitset like you said ( i cant try it t this time but i will try it later when i get home).
-
Alejandro almost 9 yearsJust tested , it is working, but I forgot something on my previous comment which I can no longer edit. Here is a live demo.
-
George almost 9 yearsthanks @ Alejandro. Can you explain the 0,2 part in the code? Thanks again :).
-
-
George almost 9 yearsThanks mate can you explain a bit your code and then i will choose it best answer.
-
vsoftco almost 9 years@George added, see if it makes sense.
-
George almost 9 yearsThanks that makes sense.
-
George almost 9 yearsI need the binary values for some outputs i need to show. I am bit lost with your example :P i will try to understand it better when i get home. Thanks.
-
George almost 9 yearsThanks @vsoftco can you explain the last line a bit more?
-
George almost 9 yearsCan you explain this part?
(arr[i],0,2)
Also thanks for the code :) -
vsoftco almost 9 years@George the one with adding 64 (XOR) was a bit unnecessary, I deleted it. What I wanted to say is that
64
in binary is0b01000000
, and adding it to the 6-bit representation ofa
orA
produces the right result. Although it's easier to do it in decimal, as I did in the main answer. -
vsoftco almost 9 yearsWhy don't you use a
std::bitset<8>
instead? In that case, it will have the same amount of bits as achar
, so you won't have any truncation, and you won't need all this mumbo-jumbo with adding stuff like64
. In fact, even 7 bits are enough to represent all ASCII characters. -
George almost 9 yearsUp-voted Also my reason of using 6 bits is that i want to have a being 000001 etc not 0b01100001 (since i am only using letters) For an encryption algorithm. It would be cumbersome to ask for the user to input his 0b01100001 instead 000001 basically :P