This question already has answers here:
How do I use an uint8_t with I/O streams while avoiding the char behavior?
(2 answers)
Closed 2 years ago.
I have implemented in C++ print_in_binary_format() function, which (as the name states) print 8-bit number in binary:
void print_in_binary_format(std::uint8_t number)
{
for (int bit_index = 7; bit_index >= 0; --bit_index) {
std::cout << ((number & (1U << bit_index)) ? '1' : '0');
}
std::cout << '\n';
}
But it doesn't work as supposed, i.e.:
Input: 2
Output: 00110010
Input: 0
Output: 00110000
I know that in C++ I could use bitset library, but it is not the case.
I would like to know what is wrong with this function, my brain is stuck!
There is whole program to test that:
#include <cstdint>
#include <iostream>
std::uint8_t read_user_number();
void print_in_binary_format(std::uint8_t number);
int main()
{
std::uint8_t number {};
number = read_user_number();
print_in_binary_format(number);
return EXIT_SUCCESS;
}
std::uint8_t read_user_number()
{
std::cout << "Enter a number (0-255): ";
std::uint8_t user_number {};
std::cin >> user_number;
return user_number;
}
void print_in_binary_format(std::uint8_t number)
{
for (int bit_index = 7; bit_index >= 0; --bit_index) {
std::cout << ((number & (1U << bit_index)) ? '1' : '0');
}
std::cout << '\n';
}
The problem is your input data. You are providing 2 or 0 as a character, not as a number.
Let me explain:
character '2' -> ASCII 0x32, 32 is the real input of your function, 00110010 is the bit representation of 0x32.
character '0' -> ASCII 0x30 has 00110000 as binary representation.
Hence the function above is working.
In order to solve the issue look at the way you are collecting the input data.
My 2 cents, Ste.
Related
This question already has answers here:
String plus Char - what is happening?
(5 answers)
C++. Why std::cout << char + int prints int value?
(2 answers)
cout and String concatenation
(3 answers)
How object cout prints multiple arguments?
(4 answers)
Closed 10 months ago.
I was experimenting with a statement in C++ using online compilers. When I try to run this specific code
cout << num[i] + " " + num[i];
The online compilers give no output. I can change the + symbol to << but I want to know the reason that the code does not give any output on these online compilers.
Online compilers that I tried are onlinegdb, programiz, and jdoodle.
#include <iostream>
#include <string>
int main() {
std::string num = "123";
int i = 0;
std::cout << num[i] + " " + num[i];
return 0;
}
C++ is not like JavaScript or many higher-level languages, as in you may not delimit you data with +'s or ,'s. As shown in Lewis' answer, each item you wish to have printed must be separated by an insertion delimiter (<<). As for extracting, you may use the extraction delimiter (>>).
In your case, you are doing mathematical operations on the the characters themselves (adding together their numerical ASCII representations together, which could print unprintable and invisible characters). The printable ASCII characters range from 32 (space character) to 127 (delete character) (base 10). When summing '1' + ' ' + '1' you are left with (49 + 32 + 49) or (130) which exceeds the printable character range. Or you may also be accessing garbage as #pm100 said in the comments due to pointer arithmetic.
Here is an example of using the insertion operator:
#include <iostream>
int main(void) {
int some_int = 1;
std::cout << "this is my " << some_int << "st answer on StackOverflow :)"
<< std::endl;
return 0;
}
And as for the extraction operator:
#include <iostream>
int main(void) {
int num;
std::cout << "Enter an integer: ";
std::cin >> num; // stores the input into the `num` variable
std::cout << "The number is: " << num << std::endl;
return 0;
}
Pointer arithmetic:
const char* get_filename(const char* _path, size_t _offset) {
return (_path + _offset);
}
// This is an example
//
// path = "path/to/my/file/file.txt";
// offset ^ ^
// 0 |
// + 16 ------------|
// path = "file.txt";
I need to covert hexadecimal string to binary then pass the bits into different variables.
For example, my input is:
std::string hex = "E136";
How do I convert the string into binary output 1110 0001 0011 0110?
After that I need to pass the bit 0 to variable A, bits 1-9 to variable B and bits 10-15 to variable C.
Thanks in advance
How do I convert the string [...]?
Start with result value of null, then for each character (starting at first, indicating most significant one) determine its value (in range of [0:15]), multiply the so far received result by 16 and add the current value to. For your given example, this will result in
(((0 * 16 + v('E')) * 16 + v('1')) * 16 + v('3')) + v('6')
There are standard library functions doing the stuff for you, such as std::strtoul:
char* end;
unsigned long value = strtoul(hex.c_str(), &end, 16);
// ^^ base!
The end pointer useful to check if you have read the entire string:
if(*char == 0)
{
// end of string reached
}
else
{
// some part of the string was left, you might consider this
// as error (could occur if e. g. "f10s12" was passed, then
// end would point to the 's')
}
If you don't care for end checking, you can just pass nullptr instead.
Don't convert back to a string afterwards, you can get the required values by masking (&) and bitshifting (>>), e. g getting bits [1-9]:
uint32_t b = value >> 1 & 0x1ffU;
Working on integrals is much more efficient than working on strings. Only when you want to print out the final result, then convert back to string (if using a std::ostream, operator<< already does the work for you...).
While playing with this sample, I realized that I gave a wrong recommendation:
std::setbase(2) does not work by standard. Ouch! (SO: Why doesn't std::setbase(2) switch to binary output?)
For conversion of numbers to string with binary digits, something else must be used. I made this small sample. Though, the separation of bits is considered as well, my main focus was on output with different bases (and IMHO worth another answer):
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <string>
std::string bits(unsigned value, unsigned w)
{
std::string text;
for (unsigned i = 0; i < w || value; ++i) {
text += '0' + (value & 1); // bit -> character '0' or '1'
value >>= 1; // shift right one bit
}
// text is right to left -> must be reversed
std::reverse(text.begin(), text.end());
// done
return text;
}
void print(const char *name, unsigned value)
{
std::cout
<< name << ": "
// decimal output
<< std::setbase(10) << std::setw(5) << value
<< " = "
// binary output
#if 0 // OLD, WRONG:
// std::setbase(2) is not supported by standard - Ouch!
<< "0b" << std::setw(16) << std::setfill('0') << std::setbase(2) << value
#else // NEW:
<< "0b" << bits(value, 16)
#endif // 0
<< " = "
// hexadecimal output
<< "0x" << std::setw(4) << std::setfill('0') << std::setbase(16) << value
<< '\n';
}
int main()
{
std::string hex = "E136";
unsigned value = strtoul(hex.c_str(), nullptr, 16);
print("hex", value);
// bit 0 -> a
unsigned a = value & 0x0001;
// bit 1 ... 9 -> b
unsigned b = (value & 0x03FE) >> 1;
// bit 10 ... 15 -> c
unsigned c = (value & 0xFC00) >> 10;
// report
print(" a ", a);
print(" b ", b);
print(" c ", c);
// done
return 0;
}
Output:
hex: 57654 = 0b1110000100110110 = 0xe136
a : 00000 = 0b0000000000000000 = 0x0000
b : 00155 = 0b0000000010011011 = 0x009b
c : 00056 = 0b0000000000111000 = 0x0038
Live Demo on coliru
Concerning, the bit operations:
binary bitwise and operator (&) is used to set all unintended bits to 0. The second value can be understood as mask. It would be more obvious if I had used binary numbers but this is not supported in C++. Hex codes do nearly as well as a hex digit represents always the same pattern of 4 bits. (as 16 = 24) After some time of practice, you usually learn to "see" the bits in the hex code.
About the right shift (>>), I was not quite sure. OP didn't require that bits have to be moved somewhere – only that they had to be separated into distinct variables. So, these right-shift's might be obsolete.
So, this question which seemed to be trivial leaded to a surprising enlightment (for me).
This question already has answers here:
Why is 'char' signed by default in C++?
(2 answers)
Is char signed or unsigned by default?
(6 answers)
Closed 5 years ago.
To find out the range of integer values for a standard 8-bit char, I ran the following code:
int counter = 0;
for (int i = -300; i <= 300; i++)
{
char c = static_cast<char> (i);
int num = static_cast<int> (c);
if (num == i)
{
counter ++;
}
else
{
cout << "Bad: " << i << "\n";
}
}
cout << "\n" << counter;
I ended up seeing a value of 256 for counter, which makes sense. However, on the list of "Bad" numbers (i.e., numbers that chars don't store), I found that the greatest Bad negative number was -129, while the smallest Bad positive number was 128.
From this test, it seems like chars only store integer values from -128 to 127. Is this conclusion correct, or am I missing something? Because I always figured chars stored integer values from 0 to 255.
Although implementation defined, for the most part - yes it is normal as your implementation defines char as a signed char. You can use the CHAR_MIN and CHAR_MAX macros to print out the minimum and maximum values of type char:
#include <iostream>
#include <cstdint>
int main() {
std::cout << CHAR_MIN << '\n';
std::cout << CHAR_MAX << '\n';
}
Or using the std::numeric_limits class template:
#include <iostream>
#include <limits>
int main() {
std::cout << static_cast<int>(std::numeric_limits<char>::min()) << '\n';
std::cout << static_cast<int>(std::numeric_limits<char>::max()) << '\n';
}
As for the 0..255 range that is the unsigned char type. Min value is 0 and max should be 255. It can be printed out using:
std::cout << UCHAR_MAX;
Whether the type is signed or not can be checked via:
std::numeric_limits<char>::is_signed;
Excerpt from the char type reference:
char - type for character representation which can be most
efficiently processed on the target system (has the same
representation and alignment as either signed char or unsigned
char, but is always a distinct type).
I have a C++ function that converts a unsigned long into a 8 bit hex char string.
I need to come up with a reverse function that takes a 8 bit hex char string and converts it into an unsigned integer representing it's bytes.
Original UINT -> char[8] method:
std::string ResultsToHex( unsigned int EncodeResults)
{
std::cout << "UINT Input ==>";
std::cout << EncodeResults;
std:cout<<"\n";
char _HexCodes[] = "0123456789ABCDEF";
unsigned int HexAccum = EncodeResults;
char tBuf[9];
tBuf[8] = '\0';
int Counter = 8;
unsigned int Mask = 0x0000000F;
char intermed;
// Start with the Least significant digit and work backwards
while( Counter-- > 0 )
{
// Get the hex digit
unsigned int tmp = HexAccum & Mask;
intermed = _HexCodes[tmp];
tBuf[Counter] = intermed;
// Next digit
HexAccum = HexAccum >> 4;
}
std::cout << "Hex char Output ==>";
std::cout << tBuf;
std::cout << "\n";
return std::string(tBuf);
}
And here is the function I am trying to write that would take a char[8] as input and convert into a UINT:
unsigned int ResultsUnhex( char tBuf[9])
{
unsigned int result = 0;
std::cout << "hex char Input ==>";
std::cout << tBuf;
std:cout<<"\n";
//CODE TO CONVERT 8 char (bit) hex char into unsigned int goes here......
//
// while() {}
//
///
std::cout << "UINT Output ==>";
std::cout << result;
std::cout << "\n";
return result;
}
I am new to bit shifts, any help would be greatly appreciated :).
You need to scan the string and convert each hexadecimal character back to it's corresponding 4 bit binary value. You can do this with a simple set of if statements that checks the character to see if it's valid and if so convert it back.
After a character has been converted, shift your result variable left by 4 bits then stuff the converted value into the lower 4 bits of the result.
#include <stdexcept>
unsigned int ConvertHexString(char *str)
{
unsigned int result = 0;
while(*str)
{
char ch = *str++;
// Check for 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9
if(ch >= '0' && ch <= '9')
{
ch -= '0';
}
// Check for a, b, c, d, e, f
else if(ch >= 'a' && ch <= 'f')
{
ch = 10 + (ch - 'a');
}
// Check for A, B, C, D, E, F
else if(ch >= 'A' && ch <= 'F')
{
ch = 10 + (ch - 'A');
}
// Opps! Invalid character
else
{
throw std::invalid_argument("Unknown character in hex string");
}
// Mmmm! Stuffing! Don't forget to check for overflow!
result = (result << 4) | ch;
}
return result;
}
There are several ways to do this but I figured a simple example to get you started would be more helpful.
Obligatory example using the conversion function.
#include <iostream>
int main()
{
std::cout
<< std::hex
<< ConvertHexString("1234567")
<< ConvertHexString("90ABCDEF")
<< std::endl;
}
Outputs...
123456790abcdef
Why do you do it manually? There's plenty of tools that do that for you. For example, stringstream.
This converts an int to a hex-string:
std::stringstream stream;
stream << std::hex << your_int;
std::string result( stream.str() );
[code copied from Integer to hex string in C++ - please see that thread, there's plenty of examples. Upvote there instead of here.]
Add to that "0x" and some field-width manipulators and you may reduce the ResultsToHex to three..five lines.
The stringstream also works the other way. Using >> operator you can just as easily read a hexstring into an integer variable. [Converting Hexadecimal to Decimal, Hex character to int in C++, convert hex buffer to unsigned int, ...]
I have to convert decimal numbers like 43.62 to binary. So i first wrote a basic program that converts 43 into binary. But I notice that my program prints out the binary number in reverse, so it prints 1 1 0 1 0 1 instead of 1 0 1 0 1 1. how can I fix this.
My Code:
#include <iostream>
using namespace std;
int main()
{
int number;
int remainder;
cout << "Enter a integer: ";
cin >> number;
while(number != 0)
{
remainder = number % 2;
cout << remainder << " ";
number /= 2;
}
int pause;
cin >> pause;
return 0;
}
Instead of sending each digit to cout, send them to an array. Then read the array out in reverse order. Or push them onto a stack, and then pop them back off the stack. Or...
Something of a sledgehammer to crack a nut, but here's a solution based on a recursive approach:
#include <iostream>
using namespace std;
void OutputDigit(int number)
{
if (number>0)
{
OutputDigit(number /= 2);
cout << number % 2 << " ";
}
}
int main()
{
OutputDigit(43);
return 0;
}
You can get the same output as you had before by simply moving the cout one line up!
Look at vector and think about how it could be useful to save the remainders instead of printing them right away.
Notice that you don't have to put things at the end of the vector. vector::insert lets you specify a position... could that be helpful?
Alternatively, the algorithm you created starts at the least significant digit. Is there a way to start from the most significant digit instead? If I have the number 42 (0101010), the most significant digit represents the 32s, and the 0 ahead of it represents the 64s. What happens if I subtract 32 from 42?
It would be easier to store the results and then print them backwards. Using recursion is also another possibility to do just that.
Most significant bit first:
const unsigned int BITS_PER_INT = CHAR_BIT * sizeof(int);
char bit_char = '0';
for (int i = BITS_PER_INT - 1;
i > 0;
--i)
{
bit_char = (value & (1 << i)) ? '1' : '0';
cout << bit_char << ' ';
}
cout << '\n';
cout.flush();
To print least significant bit first, change the direction of the for loop.
In C++, you can also use a bitset container to do this,
#include <bitset>
int i = 43;
std::bitset<sizeof(int)*CHAR_BIT> bin(i);
Just use string functions
string s ;
while(number != 0)
{
remainder = number % 2;
string c = remainder ? "1": "0";
s.insert(s.begin(),c.begin(),c.end());
number /= 2;
}
When you do such conversion by holding on to the remainder, the result will always be reverted. As suggested use bitwise &:
unsigned char bit = 0x80; // start from most significant bit
int number = 43;
while(bit)
{
if( bit & number ) // check if bit is on or off in your number
{
cout << "1";
}
else
{
cout << "0";
}
bit = bit >>1; // move to next bit
}
This example will start going through all your 8 bits of the number and check if the bit is on or off and print that accordingly.
Best option - Use C++ stringstream for formatting I/O
// Add the following headers
#include <sstream>
#include <algorithm>
// your function
stringstream ss;
// Use ss in your code instead of cout
string myString = ss.str();
std::reverse(myString.begin(),myString.end());
cout << myString;