I'm trying to write a helper function that can be used for parsing integers from config files and from a text-based protocol (written by machine, not by a human). I've read How to parse a string to an int in C++? but the solutions there don't address all the issues. I would like something that will (from most to least important):
- Reject out-of-range values. strtoul and strtoull don't quite achieve this: given a leading minus sign, the value is negated "in the return type". So "-5" is happily parsed and returns 4294967291 or 18446744073709551611 instead of signalling an error.
- Be in the C locale, regardless of the global locale setting (or even better, give me a choice). Unless there is a way to set the global locale on a per-thread basis, that rules out strtoul, stoul and boost::lexical_cast, and leaves only istringstream (where one can imbue a locale).
- Be reasonably strict. It definitely must not accept trailing garbage, and ideally I'd like to ban white space as well. That immediately makes strtol and anything based on it a little problematic. It seems that istringstream can work here using noskipws and checking for EOF, although that might just be a GCC bug.
- Ideally give some control whether the base should be assumed to be 10 or should be inferred from a 0 or 0x prefix.
Any ideas on a solution? Is there an easy way to wrap the existing parsing machinery to meet these requirements, or is it going to end up being less work to write the parser myself?