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 for char
, signed char
and unsigned char
, which all read a single character from the stream. A uint8_t
argument selects the unsigned char
overload as the best match, reading F
as a character (ASCII code 70 or 0x46).
To match an integer extraction operator>>
overload, use an argument of type short
or bigger (for example, uint16_t
):
std::uint16_t n = 0;
std::stringstream ss;
ss << 'F';
ss >> std::hex >> n;
Can I cast to int at the point of the read from the stringstream?
No. The argument is taken by reference, which in function calls works as a pointer. Type punning a uint8_t
argument as (int&)
will invoke undefined behavior. Just use a bigger type instead.