Home > database >  C : Parse decimal from stream into uint8_t
C : Parse decimal from stream into uint8_t

Time:04-02

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);

CodePudding user response:

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
    }
}

CodePudding user response:

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

  • Related