Given a string that should represent a number, I'd like to put it into a conversion function which would provide notification if the whole string did not convert.
For input: "12"
:
istringstream::operator>>
outputs 12atoi
outputs 12stoi
outputs 12
For input "1X"
I'd like a failure response but I get:
istringstream::operator>>
outputs 1atoi
outputs 1stoi
outputs 1
For input "X2"
:
istringstream::operator>>
outputs 0 and sets an error flagatoi
outputs 0stoi
throws an error
Is there a way to provoke the error behavior on input "1X"
?
Alternatively you can use
std::istringstream
as you mentioned, but check to make sure it parsed to the end of the stream. Assuming you have a constant reference, you could do something like the followingThe benefit of this approach is that you parse anything that overloads
operator>>
. Note: I'm not entirely sure if the condition is enough, but with my testing it seemed to be. For some reason the stream would get a failure marking if it parsed to the end.For a given
string str
there are several ways to accomplish this each with advantages and disadvantages. I've written a live example here: https://ideone.com/LO2Qnq and discuss each below:strtol
As suggested here
strtol
's out-parameter can be used to get the number of characters read.strtol
actually returns along
not anint
so a cast is happening on the return.Note that this uses
i.c_str()
to refer to the same string.c_str
Returns pointer to the underlying array serving as character storage not a temporary if you have C++11:Also note that the pointer returned by
c_str
will be valid between thestrtol
anddistance
calls unless:If you violate either of these cases you'll need to make a temporary copy of
i
's underlyingconst char*
and perform the test on that.sscanf
sscanf
can use%zn
to return the number of characters read which may be more intuitive than doing a pointer comparison. If base is important,sscanf
may not be a good choice. Unlikestrtol
andstoi
which support bases 2 - 36,sscanf
provides specifiers for only octal (%o
), decimal (%d
), and hexadecimal (%x
).stoi
As suggested here
stoi
's output parameter works likesscanf
's%n
returning the number of characters read. In keeping with C++ this takes astring
and unlike the C implementations abovestoi
throws aninvalid_argument
if the first non-whitespace character is not considered a digit for the current base, and this unfortunately means that unlike the C implementations this must check for an error in both thetry
andcatch
blocks.