Convert 16 bits to 4 char ( in Hexadecimal) - c++

I want to convert 16 bit to 4 characters which are in Hexadecimal character.
For example, a 16 bit, 1101 1010 1101 0001 in hexadecimal is DAD1 and in decimal is 56017. Now I want to convert this 16 bit into DAD1 as characters so that I can use the character to write into a text file.
My coding part, my variable "CRC" is my result from CRC checksum. Now I want to convert 16 bit "CRC" into 4 characters which are DAD1 (capital letters).
cout << hex << CRC<<endl;
char lo = CRC & 0xFF;
char hi = CRC >> 8;
cout << hi << endl;
cout << lo;
*******Result********
dad1
┌
₸

Try this:
#include <iostream>
#include <bitset>
#include <string>
int main()
{
int i = 56017;
std::cout <<hex <<i << std::endl;
std::bitset<16> bin = i;
std::string str = bin.to_string();
std::bitset<8> hi(str.substr(0, 8));
std::bitset<8> lo(str.substr(8, 8));
std::cout << bin << std::endl;
std::cout << hi << " " << hi.to_ullong() << std::endl;
std::cout << lo << " " << lo.to_ullong() << std::endl;
}
OR you can also do
std::cout <<hex << (CRC & 0xFF)<< std::endl;
std::cout << hex << (CRC >> 8) << std::endl;
Output:

Try This :
#include <iostream>
#include <bitset>
#include <limits>
int main()
{
int i = 56017;
std::bitset<std::numeric_limits<unsigned long long>::digits> b(i);
std::cout<< std::hex << b.to_ullong();
}

Related

Reorder byte order for an array of 24-bit bytes using endian manipulations in arduino/c/c++?

I have a 24-bit array:
uint32_t rgbdata[] = { 0x00ff00 0xff0000 0x0000ff ...... }
Let's say the above data is in RGB order and I want GRB order
uint32_t grbdata[] = { 0xff0000 0x00ff00 0x0000ff ...... }
Without using loops, is there a quick endian manipulation way to do a certain byte order? Speed is of utmost importance in this case.
Here is a partial example of a uint24_t that you might port to your tools (I don't know the 'current' arduino's tool set)
// Note: compile with -std=c++17 for the using comma list
// or remove these and put the "std::" into code
#include <algorithm>
using std::swap;
#include <iostream>
using std::cout, std::cerr, std::endl, std::hex, std::dec, std::cin; // c++17
#include <string>
using std::string, std::to_string; // c++17
#include <sstream>
using std::stringstream;
class Uint24_t
{
public:
Uint24_t() : data {0,0,0}
{
cout << "\n sizeof(Uint24_t)= " << sizeof(Uint24_t) // reports 3 bytes
<< " bytes, * 8= " << (sizeof(Uint24_t) * 8) << " bits." << endl;
}
Uint24_t(uint32_t initVal) : data {0,0,0}
{
data[0] = static_cast<uint8_t>((initVal >> 0) & 0xff); // lsbyte
data[1] = static_cast<uint8_t>((initVal >> 8) & 0xff); //
data[2] = static_cast<uint8_t>((initVal >> 16) & 0xff); // msbyte
cout << "\n sizeof(Uint24_t)= " << sizeof(Uint24_t) // reports 3 bytes
<< " bytes, * 8= " << (sizeof(Uint24_t) * 8) << " bits." << endl;
}
~Uint24_t() = default;
std::string show() {
stringstream ss;
ss << " show(): "
<< static_cast<char>(data[2]) << "."
<< static_cast<char>(data[1]) << "."
<< static_cast<char>(data[0]);
return ss.str();
}
std::string dump() {
stringstream ss;
ss << " dump(): " << hex
<< static_cast<int>(data[2]) << "."
<< static_cast<int>(data[1]) << "."
<< static_cast<int>(data[0]);
return ss.str();
}
void swap0_2() { swap(data[0], data[2]); }
private:
uint8_t data[3]; // 3 uint8_t 's
};
class T976_t // ctor and dtor compiler provided defaults
{
public:
int operator()() { return exec(); } // functor entry
private: // methods
int exec()
{
Uint24_t u24(('c' << 16) + // msbyte
('b' << 8) +
('a' << 0));
cout << "\n sizeof(u24) = " << sizeof(u24) << " bytes"
<< "\n " << u24.show()
<< "\n " << u24.dump() << std::endl;
u24.swap0_2(); // swapping lsByte and msByte
cout << "\n sizeof(u24) = " << sizeof(u24) << " bytes"
<< "\n " << u24.show()
<< "\n " << u24.dump() << std::endl;
return 0;
}
}; // class T976_t
int main(int , char**) { return T976_t()(); } // call functor
Typical output:
sizeof(Uint24_t)= 3 bytes, * 8= 24 bits.
sizeof(u24) = 3 bytes
show(): c.b.a
dump(): 63.62.61
sizeof(u24) = 3 bytes
show(): a.b.c
dump(): 61.62.63

What could change display width?

I have a SystemC function with signature:
sc_dt::sc_uint<12> Get()
and the lines:
cerr << "[" << hex << setw(3) << setfill('0') << 0 << dec << "]\n";
cerr << "[" << hex << setw(3) << setfill('0') << Get() << dec << "]\n";
result in this output:
[000]
[0000]
Why does the displayed width change from 3 to 4?
#include <systemc.h>
#include <iostream>
#include <iomanip>
int sc_main(int argc, char* argv[])
{
sc_dt::sc_uint <12> my_uint = 0;
std::cerr << std::hex << my_uint << std::endl;
}
g++ test.cpp -lsystemc && ./a.out prints this:
SystemC 2.3.1-Accellera --- Jul 24 2017 21:50:41
Copyright (c) 1996-2014 by all Contributors,
ALL RIGHTS RESERVED
0000
It is showing four zeros (for 16 bits) instead of three (for 12 bits), as you probably expected it would, because that is how 12-bit integer is implemented in SystemC. And it doesn't get shortened by std::setw because it sets the minimum number of characters to be written. If there are more characters, then all of them will get written. Also to mention, the std::dec in your example does nothing because there are no numbers printed afterwards.
http://www.cplusplus.com/reference/ios/ios_base/width/
http://www.cplusplus.com/reference/iomanip/setw/
This will print only last 3 characters for lower 12 bits:
#include <systemc.h>
#include <iostream>
#include <iomanip>
const unsigned CHARS = 3;
const unsigned MASK = (1u << CHARS * 4) -1; // Same as 0xFFF
int sc_main(int argc, char* argv[])
{
sc_dt::sc_uint <12> my_uint = 0xABC;
std::cerr << std::hex
<< std::setw (CHARS) << std::setfill ('0')
<< (my_uint & MASK) << std::endl;
}

Why do I have to cast a byte as unsigned twice to see hex output? [duplicate]

This question already has answers here:
Are int8_t and uint8_t intended to be char types?
(5 answers)
Closed 7 years ago.
I want to print a variable as hex:
#include <iostream>
#include <string>
#include <cstdint>
int main() {
auto c = 0xb7;
std::cout << std::hex << static_cast<unsigned char>(c) << std::endl;
std::cout << std::hex << static_cast<unsigned>(static_cast<unsigned char>(c)) << std::endl;
std::cout << std::hex << (uint8_t)(c) << std::endl;
std::cout << std::hex << (unsigned)(uint8_t)(c) << std::endl;
return 0;
}
The output seems to be:
\ufffd (tries to print it as a char)
b7
\ufffd (tries to print it as a char)
b7
I do understand that c has higher bits set (10110111), but I cast it to uint8_t and unsigned char once already.
Why do I have to cast uint8_t or unsigned char to unsigned again to get the expected output?
std::hex sets the basefield of the stream str to hex as if by calling str.setf(std::ios_base::hex, std::ios_base::basefield).
When this basefield hex bit is set, iostreams use hexadecimal base for integer I/O.
Code
#include <iostream>
int main()
{
int i = 0xb7;
unsigned u = 0xb7;
char c = static_cast<char>(0xb7);
unsigned char b = 0xb7;
std::cout << std::hex << i << std::endl;
std::cout << std::hex << u << std::endl;
std::cout << std::hex << c << std::endl;
std::cout << std::hex << b << std::endl;
return 0;
}
Output
b7
b7
�
�
I suspect this output to vary on a Windows (non UTF-8) system.

char, hex, because it shows ffffff

I have a char [], with the buffer name, the data is saved using an ifstream in binary mode,
void File::mostrarBuffer(){
for (int a = 0; a < std::strlen(buffer); a++){
std::cout << std::hex << ((int)buffer[a]) << std::endl;
}
// para ver char test, only for test
std::cout << "===" << std::endl;
for (int a = 0; a < std::strlen(buffer); a++){
std::cout << buffer[a] << std::endl;
}
char charTest = '\211';
std::cout << "===" << std::endl;
std::cout << std::hex << (int)charTest << std::endl;
std::cout << std::hex << (int)buffer[0] << std::endl;
}
the shell out:
ffffff89
50
4e
47
===
\211
P
N
G
===
ffffff89
ffffff89
the file in hexdump ("little-endian"):
0000000 5089 474e 0a0d 0a1a 0000 0d00 4849 5244
my question is why, appears ffffff89 and not 89, and only on the first element of char [] I've been around with this and can not find the solution. thanks for reading.
this solution works for me:
std::cout << std::hex << ((unsigned int)(unsigned char)buffer[a])
<< std::endl;
Because your chars are signed (highest bit is set).
I'm sorry, I'm not familiar with using std::hex but you somehow need to treat it like an unsigned char value. Try casting the char to and unsigned type.

C++ cout hex format

i am a c coder, new to c++.
i try to print the following with cout with strange output. Any comment on this behaviour is appreciated.
#include<iostream>
using namespace std;
int main()
{
unsigned char x = 0xff;
cout << "Value of x " << hex<<x<<" hexadecimal"<<endl;
printf(" Value of x %x by printf", x);
}
output:
Value of x ÿ hexadecimal
Value of x ff by printf
<< handles char as a 'character' that you want to output, and just outputs that byte exactly. The hex only applies to integer-like types, so the following will do what you expect:
cout << "Value of x " << hex << int(x) << " hexadecimal" << endl;
Billy ONeal's suggestion of static_cast would look like this:
cout << "Value of x " << hex << static_cast<int>(x) << " hexadecimal" << endl;
You are doing the hex part correctly, but x is a character, and C++ is trying to print it as a character. You have to cast it to an integer.
#include<iostream>
using namespace std;
int main()
{
unsigned char x = 0xff;
cout << "Value of x " << hex<<static_cast<int>(x)<<" hexadecimal"<<endl;
printf(" Value of x %x by printf", x);
}
If I understand your question correctly, you should expect to know how to convert hex to dec since you have already assigned unsigned char x = 0xff;
#include <iostream>
int main()
{
unsigned char x = 0xff;
std::cout << std::dec << static_cast<int>(x) << std::endl;
}
which shall give the value 255 instead.
Further detail related to the the str stream to dec shall refer in http://www.cplusplus.com/reference/ios/dec/.
If you want to know the hexadecimal value from the decimal one, here is a simple example
#include <iostream>
#include <iomanip>
int main()
{
int x = 255;
std::cout << std::showbase << std::setw(4) << std::hex << x << std::endl;
}
which prints oxff.
The library <iomanip> is optional if you want to see 0x ahead of ff. The original reply related to hex number printing was in http://www.cplusplus.com/forum/windows/51591/.