'C++: Parse decimal from stream into uint8_t
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.
Solution 1:[1]
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
}
}
Solution 2:[2]
You can directly stream the input into a uint8_t variable like so:
uint8_t actual;
std::cin >> std::dec >> actual;
If your input is too large, say you entered "12000", your actual variable will hold the value of 1
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Artyer |
| Solution 2 | Albert Slepak |
