C++ struct data member - c++

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.

Related

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

#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.

unsigned long cannot hold the correct number over 2,147,483,647

Source Code:
#include <iostream>
using namespace std;
int main() {
unsigned long P;
P = 0x7F << 24;
cout << P << endl;
P = 0x80 << 24;
cout << P << endl;
return 0;
}
Output:
2130706432
18446744071562067968
As you can see, the first result is correct.
But the second result is extremely wrong.
The expected result is 2147483648 and it does not match with 18446744071562067968.
I want to know why
The type of the expression 0x80 << 24 is not unsigned long, it’s int. You then assign the result of that expression to P, and in the process convert it to an unsigned long. But at that point it has already overflown (incidentally causing undefined behaviour). Use unsigned long literals in your expression:
P = 0x80ul << 24;
This problem is not entirely portable, since it depends on the number of bits in your representation of unsigned long. In this case, there is an overflow followed by an underflow, and the two effects combine to produce your surprising result.
The basic solution is indicated here: ULL suffix on a numeric literal
I've broken it down in the code below.
#include <iostream>
using namespace std;
int main() {
cout << "sizeof(unsigned long) = " << sizeof(unsigned long) << "\n";
cout << "sizeof(0x80) = " << sizeof(0x80) << "\n";
int32_t a = (0x80 << 24); // overflow: positive to negative
uint64_t b = a; // underflow: negative to positive
uint64_t c = (0x80 << 24); // simple broken
uint64_t d = (0x80UL << 24); // simple fixed
uint32_t e = (0x80U << 24); // what you probably intended
cout << "a = " << a << "\n";
cout << "b = " << b << "\n";
cout << "c = " << c << "\n";
cout << "d = " << d << "\n";
cout << "e = " << e << "\n";
}
Output:
$ ./c-unsigned-long-cannot-hold-the-correct-number-over-2-147-483-647.cpp
sizeof(unsigned long) = 8
sizeof(0x80) = 4
a = -2147483648
b = 18446744071562067968
c = 18446744071562067968
d = 2147483648
e = 2147483648
If you're doing bit-shift operations like this, it probably makes sense to be explicit about the integer sizes (as I have shown in the code above).
What's the difference between long long and long
Fixed width integer types (since C++11)

How do I use an uint8_t with I/O streams while avoiding the char behavior?

Consider this simple C++ program:
#include <cstdint>
#include <iostream>
int main() {
uint8_t var;
std::cin >> var;
std::cout << "var = " << var << '\n';
if (var == 1) {
std::cout << "var is 1\n";
} else {
std::cout << "var is not 1\n";
}
}
Running it shows some surprising behavior. When the input is 1, the output is
var = 1
var is not 1
which is clearly absurd! After quite a few varied tests, I realized what is happening—it's reading and writing a char! Still, it's not the behavior I want—I used uint8_t because I want the integer behavior. How can I make uint8_t behave like the other integer types when doing stream I/O? Alternatively, what one-byte type should I use instead?
How can I make uint8_t behave like the other integer types when doing stream I/O?
You can't. Apparently you can.
If std::uint8_t is an alias of unsigned char, as it usually (maybe always) is, then it is a character type, and the standard streams treat it as a character type.
You can convert it to a non-character integer type before inserting to a stream:
std::cout << "var = " << static_cast<unsigned>(var) << '\n';
Or with an intermediary variable:
unsigned temp = var;
std::cout << "var = " << temp << '\n';
Stream extraction works only with the intermediary variable approach:
unsigned temp;
std::cin >> temp;
var = temp;
On a related note, if you wish to output the address of a variable, then std::cout << &var; won't work, because it will be treated as a null terminated string... which it isn't and thus results in undefined behaviour. To achieve that, you can use std::cout << static_cast<void*>(&var);.
You need to cast to int:
std::cout << "var = " << static_cast<int>(var) << '\n';
or shorter (C-style):
std::cout << "var = " << (int)var << '\n'; //or:
std::cout << "var = " << int(var) << '\n'; //constructor-like
or even shorter (promoting to int with an arithmetic operator):
std::cout << "var = " << +var << '\n';

INTtoCHAR function couts wrong value

here is what my function looks like:
signed char INTtoCHAR(int INT)
{
signed char CHAR = (signed char)INT;
return CHAR;
}
int CHARtoINT(signed char CHAR)
{
int INT = (int)CHAR;
return INT;
}
It works properly that it assigns the int value to the char, but when I want to cout that char then it gives me some weired signs. It compiles without errors.
My testing code is:
int main()
{
int x = 5;
signed char after;
char compare = '5';
after = INTtoCHAR(5);
if(after == 5)
{
std::cout << "after:" << after << "/ compare: " << compare << std::endl;
}
return 0;
}
After is indeed 5 but it doesn't print 5. Any ideas?
Adding to the above answer using the unary operator +, there is another way as well: typecasting.
std::cout << "after:" << (int)after << "/ compare: " << compare << std::endl;
Correct output
Use +after while printing, instead of after. This will promote after to a type printable as a number, regardless of type.
So change this:
std::cout << "after:" << after << ", compare: " << compare << std::endl;
to this:
std::cout << "after:" << +after << ", compare: " << compare << std::endl;
For more, see this answer.

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.