I suppose the fact that std::uint8_t is really just an alias for char means that when the characters in the stringstream get read back in, they are stored natively, i.e. the ascii code for the character, whereas if the char is input to an int, with std::hex specified, it gets read in as a hex digit converted to base 10.
This is a small example exhibiting the behavior, but the reason I'm asking is because I started out under the assumption that specifying an output vector of std::uint8_t was the right approach, as I need to later feed this vector as an array to a C function as a byte vector (you pass it in as a void pointer and it figures out what do to with it somehow). So I figured reading in pairs of input chars into a string stream and then out into a std::uint8_t would help me skip manually bitshifting. Is there a way of keeping the idea of reading into a std::uint8_t but invoking the handling of an int? Can I cast to int at the point of the read from the stringstream? Or what?
#include <iostream>
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <vector>
#include <cstdint>
int main (int argc, char** argv) {
uint8_t n = 0;
std::stringstream ss;
ss << 'F';
ss >> std::hex >> n;
std::cout << "uint8:" << (int)n << std::endl;
int m = 0;
std::stringstream tt;
tt << 'F';
tt >> std::hex >> m;
std::cout << "int:" << std::hex << m << std::endl;
return 0;
}
output
uint8:70
int:f
There are
operator>>overloads forchar,signed charandunsigned char, which all read a single character from the stream. Auint8_targument selects theunsigned charoverload as the best match, readingFas a character (ASCII code 70 or 0x46).To match an integer extraction
operator>>overload, use an argument of typeshortor bigger (for example,uint16_t):No. The argument is taken by reference, which in function calls works as a pointer. Type punning a
uint8_targument as(int&)will invoke undefined behavior. Just use a bigger type instead.