std::cout print char as 2-digit hex [duplicate] - c++

#include <iostream>
using namespace std;
int main()
{
char c1 = 0xab;
signed char c2 = 0xcd;
unsigned char c3 = 0xef;
cout << hex;
cout << c1 << endl;
cout << c2 << endl;
cout << c3 << endl;
}
I expected the output are as follows:
ab
cd
ef
Yet, I got nothing.
I guess this is because cout always treats 'char', 'signed char', and 'unsigned char' as characters rather than 8-bit integers. However, 'char', 'signed char', and 'unsigned char' are all integral types.
So my question is: How to output a character as an integer through cout?
PS: static_cast(...) is ugly and needs more work to trim extra bits.

char a = 0xab;
cout << +a; // promotes a to a type printable as a number, regardless of type.
This works as long as the type provides a unary + operator with ordinary semantics. If you are defining a class that represents a number, to provide a unary + operator with canonical semantics, create an operator+() that simply returns *this either by value or by reference-to-const.
source: Parashift.com - How can I print a char as a number? How can I print a char* so the output shows the pointer's numeric value?

Cast them to an integer type, (and bitmask appropriately!) i.e.:
#include <iostream>
using namespace std;
int main()
{
char c1 = 0xab;
signed char c2 = 0xcd;
unsigned char c3 = 0xef;
cout << hex;
cout << (static_cast<int>(c1) & 0xFF) << endl;
cout << (static_cast<int>(c2) & 0xFF) << endl;
cout << (static_cast<unsigned int>(c3) & 0xFF) << endl;
}

Maybe this:
char c = 0xab;
std::cout << (int)c;
Hope it helps.

Another way is to overload the << operator:
#include <iostream>
using namespace std;
typedef basic_ostream<char, char_traits<char>> basicOstream;
/*inline*/ basicOstream &operator<<(basicOstream &stream, char c) {
return stream.operator<<(+c);
}
/*inline*/ basicOstream &operator<<(basicOstream &stream, signed char c) {
return stream.operator<<(+c);
}
/*inline*/ basicOstream &operator<<(basicOstream &stream, unsigned char c) {
return stream.operator<<(+c);
}
int main() {
char var1 = 10;
signed char var2 = 11;
unsigned char var3 = 12;
cout << var1 << endl;
cout << var2 << endl;
cout << var3 << endl;
return 0;
}
which prints the following output:
10
11
12
Process finished with exit code 0
I think it's very neat and useful. hope it hepls!
And Also if you want it to print a hex value you can do like this:
basicOstream &operator<<(basicOstream &stream, char c) {
return stream.operator<<(hex).operator<<(c);
} // and so on...

What about:
char c1 = 0xab;
std::cout << int{ c1 } << std::endl;
It's concise and safe, and produces the same machine code as other methods.

Another way to do it is with std::hex apart from casting (int):
std::cout << std::hex << (int)myVar << std::endl;
I hope it helps.

Related

how to initialize an unsigned integer uint8_t

How to use uint8_t and to initialize a variable
#include<iostream>
using namespace std;
int main()
{
uint8_t a = 6;
cout << a;
return 1;
}
It is printing some symbol
C++ treats uint8_t as char - because that's pretty much what it is.
If you pass a char to cout, it'll print as a char, which, with a value of 6, is the ACK symbol (which would probably display strangely, depending on your terminal settings).
If you want it to be printed as a number, casting it to an unsigned in cout should do the trick:
cout << (unsigned)a;
You can cast the variable a in order to print that as a number and not an ascii symbol
#include<iostream>
#include <cstdint>
int main()
{
uint8_t a = 6;
std::cout << "a: " << a << std::endl;
std::cout << "a casted to char(is the same type actually): " << char(a) << std::endl;
std::cout << "a casted to int: " << int(a) << std::endl;
getchar();
return 0;
}
You can use good old type-unsafe printf.
#include <cstdint>
#include <cstdio>
int main()
{
std::uint8_t a = 6;
std::printf("%d\n", a);
}

C++ Why bitwise operator ~ on uint64_t and uint8_t return different types?

#include <stdio.h>
#include <iostream>
int main()
{
using namespace std;
uint64_t a = 3;
if (uint64_t(~a) == (~a))
cout << "right" << endl;//right
else
cout << "wrong" << endl;
cout << sizeof(~a) << endl;//8
uint8_t b = 3;
if (uint8_t(~b) == (~b))
cout << "right" << endl;
else
cout << "wrong" << endl;//wrong
cout << sizeof(~b) << endl;//4
getchar();
return 0;
}
~uint8_t returns int value,but ~uint64_t returns uint64_t .
Is this undefined behaviour ?
Posting from en.cppreference
The result of operator~ is the bitwise NOT (one's complement) value
of the argument (after promotion).
Integral promotion is applied to char, short int etc (types narrower than int) and the result needs to be casted to destination type if destination is not int.
This is the reason for sizeof(~b) == sizeof(int) in your case.

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.

How to output a character as an integer through cout?

#include <iostream>
using namespace std;
int main()
{
char c1 = 0xab;
signed char c2 = 0xcd;
unsigned char c3 = 0xef;
cout << hex;
cout << c1 << endl;
cout << c2 << endl;
cout << c3 << endl;
}
I expected the output are as follows:
ab
cd
ef
Yet, I got nothing.
I guess this is because cout always treats 'char', 'signed char', and 'unsigned char' as characters rather than 8-bit integers. However, 'char', 'signed char', and 'unsigned char' are all integral types.
So my question is: How to output a character as an integer through cout?
PS: static_cast(...) is ugly and needs more work to trim extra bits.
char a = 0xab;
cout << +a; // promotes a to a type printable as a number, regardless of type.
This works as long as the type provides a unary + operator with ordinary semantics. If you are defining a class that represents a number, to provide a unary + operator with canonical semantics, create an operator+() that simply returns *this either by value or by reference-to-const.
source: Parashift.com - How can I print a char as a number? How can I print a char* so the output shows the pointer's numeric value?
Cast them to an integer type, (and bitmask appropriately!) i.e.:
#include <iostream>
using namespace std;
int main()
{
char c1 = 0xab;
signed char c2 = 0xcd;
unsigned char c3 = 0xef;
cout << hex;
cout << (static_cast<int>(c1) & 0xFF) << endl;
cout << (static_cast<int>(c2) & 0xFF) << endl;
cout << (static_cast<unsigned int>(c3) & 0xFF) << endl;
}
Maybe this:
char c = 0xab;
std::cout << (int)c;
Hope it helps.
Another way is to overload the << operator:
#include <iostream>
using namespace std;
typedef basic_ostream<char, char_traits<char>> basicOstream;
/*inline*/ basicOstream &operator<<(basicOstream &stream, char c) {
return stream.operator<<(+c);
}
/*inline*/ basicOstream &operator<<(basicOstream &stream, signed char c) {
return stream.operator<<(+c);
}
/*inline*/ basicOstream &operator<<(basicOstream &stream, unsigned char c) {
return stream.operator<<(+c);
}
int main() {
char var1 = 10;
signed char var2 = 11;
unsigned char var3 = 12;
cout << var1 << endl;
cout << var2 << endl;
cout << var3 << endl;
return 0;
}
which prints the following output:
10
11
12
Process finished with exit code 0
I think it's very neat and useful. hope it hepls!
And Also if you want it to print a hex value you can do like this:
basicOstream &operator<<(basicOstream &stream, char c) {
return stream.operator<<(hex).operator<<(c);
} // and so on...
What about:
char c1 = 0xab;
std::cout << int{ c1 } << std::endl;
It's concise and safe, and produces the same machine code as other methods.
Another way to do it is with std::hex apart from casting (int):
std::cout << std::hex << (int)myVar << std::endl;
I hope it helps.

C++ struct data member

I am working in C++, Linux and I encounter the problem as following:
struct testing{
uint8_t a;
uint16_t b;
char c;
int8_t d;
};
testing t;
t.a = 1;
t.b = 6;
t.c = 'c';
t.d = 4;
cout << "Value of t.a >>" << t.a << endl;
cout << "Value of t.b >>" << t.b << endl;
cout << "Value of t.c >>" << t.c << endl;
cout << "Value of t.d >>" << t.d << endl;
The output on my console is:
Value of t.a >>
Value of t.b >>6
Value of t.c >>c
Value of t.d >>
It seems like the t.a and t.d is missing for the int8_t and uint8_t type. Why is it so?
Thanks.
The int8_t and uint8_t types are probably defined as char and unsigned char. The stream << operator is going to output them as characters. Since they're set to 1 and 4 respectively, which are control characters and not printing characters, nothing will be visible on the console. Try setting them to 65 and 66 ('A' and 'B') and see what happens.
EDIT: to print out a numeric value instead of a character, you will need to cast them to an appropriate type:
cout << static_cast<unsigned int>(t.a) << endl;
This is because those variables are being treated as 'char' type when selecting the operator<< overload.
Try:
cout << "Value of t.a >>" << static_cast<int>(t.a) << endl;
In this linux man page, int8_t and uint8_t are in fact typedefed as char:
typedef signed char int8_t
typedef unsigned char uint8_t
And the value 1 and 4 of char are control characters, as you can find here.
That is why you see nothing printed.