Read uint8_t from std::stringstream as a numeric type

  • A+

My understanding is that reading a uint8_t from a stringstream is a problem because the stringstream will interpret the uint8_t as a char. I would like to know how I can read a uint8_t from a stringstream as a numeric type. For instance, the following code:

#include <iostream> #include <sstream>  using namespace std;  int main() {     uint8_t ui;     std::stringstream ss("46");     ss >> ui;     cout << unsigned(ui);     return 0; } 

prints out 52. I would like it to print out 46.

EDIT: An alternative would to just read a string from the stringstream and then convert the solution to uint8_t, but this breaks the nice chaining properties. For example, in the actual code I have to write, I often need something like this:

   void foobar(std::istream & istream){        uint8_t a,b,c;        istream >> a >> b >> c;        // TODO...    } 


You can overload the input operator>> for uint8_t, such as:

std::stringstream& operator>>(std::stringstream& str, uint8_t& num) {    uint16_t temp;    str >> temp;    /* constexpr */ auto max = std::numeric_limits<uint8_t>::max();    num = std::min(temp, (uint16_t)max);    if (temp > max) str.setstate(std::ios::failbit);    return str; } 

Live demo:

To say the truth I am not sure whether such a solution is problem-free. Someone more experienced might clarify.


Note that this solution is not generally applicable to std::basic_istream (as well as it's instance std::istream), since there is an overloaded operator>> for unsigned char: [istream.extractors]. The behavior will then depend on how uint8_t is implemented.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: