Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With std::istream::operator>> working on unsigned types, how do I tell apart a failed extraction from an underflow?

Tags:

c++

io

iostream

I want to use std::istream::operator>> to extract data into unsigned types (that's inside a template so it can be ushort, uint, etc). Specifically, I'm using std::stringstream to parse std::string lines extracted from a file with std::getline() calls.

Since I'm reading from a file, those extractions can fail for different reasons: underflow, overflow and "bad extraction". Such cases are handled by the STL:

If extraction fails, zero is written to value and failbit is set. If extraction results in the value too large or too small to fit in value, std::numeric_limits::max() or std::numeric_limits::min() is written and failbit flag is set.

source: cppreference

Problem: std::numeric_limits::min() equals 0 for unsigned types, so there's no way to know if I'm reading something that isn't an integer (in which case I'm aborting the program) or if it's just an underflow (in which case I'm just clamping the value and emitting a warning).

How do I solve this without using bigger and/or signed equivalents of the unsigned type I'm working with?

like image 227
m88 Avatar asked Nov 07 '22 13:11

m88


1 Answers

Unsigned type won't underflow. If you mean "underflow" by inputting a negative number, the standard stream does not treat it as an error. The negative number is wrapped around into the unsigned type, and failbit is NOT set.

Hence, if you see 0 stored and failbit is set, you can assert it is an extraction failure. To detect negative number error, you have to do some extra work. For example, you can first read the value in an (large enough) signed integer type to detect if it is negative.

like image 157
xskxzr Avatar answered Nov 15 '22 06:11

xskxzr