Is there a way to do the following directly using stream operators?
uint8_t actual;
uint32_t temporary;
std::cin >> std::dec >> temporary;
if (temporary > UINT8_MAX) {
// error
}
actual = static_cast<uint8_t>(temporary);
In particular, I would like to parse a sufficiently small decimal number into a uint8_t without resorting to a larger temporary variable.
No, I don't think there is a way to read a number directly into unsigned char with a std::istream (std::num_get::get doesn't support unsigned char)
You could encapsulate it into a function:
inline std::uint8_t read_uint8(std::istream& is) {
unsigned short temporary;
is >> temporary;
if (!is) return -1;
if (temporary > UINT8_MAX) {
is.setstate(std::ios_base::failbit);
return -1;
}
return std::uint8_t(temporary);
}
int main() {
std::uint8_t actual = read_uint8(std::cin);
if (!std::cin) {
// error
}
}
Or you can do something like what std::put_money or std::osyncstream does and wrap one of the arguments to call a custom operator>>:
struct read_uint8 {
std::uint8_t& v;
read_uint8(std::uint8_t& v) : v(v) {}
};
inline std::istream& operator>>(std::istream& is, read_uint8 v) {
unsigned short temporary;
is >> temporary;
if (is) {
if (temporary > UINT8_MAX) {
is.setstate(std::ios_base::failbit);
} else {
v.v = std::uint8_t(temporary);
}
}
return is;
}
int main() {
std::uint8_t actual;
if (!(std::cin >> read_uint8(actual))) {
// error
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With