_wtoi when can't convert input, so input isn't integer, returns zero. But the same time input can be zero. Is it a way to determine if there was wrong input or zero?
Asked
Active
Viewed 2,988 times
4
-
3Nope, which is why no one uses `atoi`/`wtoi` in real code. – ildjarn May 21 '12 at 16:19
-
1Indeed, [wcstol()](http://msdn.microsoft.com/en-us/library/w4z2wdyc) does the job better. – Frédéric Hamidi May 21 '12 at 16:21
-
@FrédéricHamidi from MSDN: "returns 0 if no conversion can be performed", so the same problem – Alecs May 21 '12 at 16:43
-
@ildjarn can you advise what I can use instead? – Alecs May 21 '12 at 16:44
-
@Alecs, true but `if endptr is not NULL, a pointer to the character that stopped the scan is stored at the location pointed to by endptr. If no conversion can be performed (no valid digits were found or an invalid base was specified), the value of nptr is stored at the location pointed to by endptr`. So you can check if `0` was returned because the input is invalid or because it actually is `0`. – Frédéric Hamidi May 21 '12 at 16:44
-
@Alecs : This being C++, standard string streams (specifically, [`std::wistringstream`](http://en.cppreference.com/w/cpp/io/basic_istringstream) in this case), or [Boost.Spirit](http://www.boost.org/libs/spirit/).Qi if you really value runtime performance over compile times. – ildjarn May 21 '12 at 16:47
-
1@FrédéricHamidi in the end I used wcstol(), so please add an answer to the question consisting of your comments so I will be able to accept it, it will be fair. – Alecs May 21 '12 at 18:08
-
1`wcstol` is `strtol`: http://msdn.microsoft.com/en-us/library/w4z2wdyc.aspx – Mahmoud Al-Qudsi May 21 '12 at 18:17
-
@Alecs, Mahmoud demonstrates how to use it in his answer, so... the information is already there, my answer would be redundant :) – Frédéric Hamidi May 21 '12 at 19:02
-
@FrédéricHamidi ok, as you wish) – Alecs May 22 '12 at 09:45
-
@MahmoudAl-Qudsi yes, I know, but Frédéric Hamidi wrote about it before your answer, and I have read your answer after I already used wcstol, that's why I proposed him to post an answer =) but he don't want, so i will accept yours :-) – Alecs May 22 '12 at 09:47
1 Answers
5
This is C++, you should be using stringstream
to do your conversion:
#include <iostream>
#include <sstream>
int main()
{
using namespace std;
string s = "1234";
stringstream ss;
ss << s;
int i;
ss >> i;
if (ss.fail( ))
{
throw someWeirdException;
}
cout << i << endl;
return 0;
}
A cleaner and easier solution exists with boost's lexical_cast
:
#include <boost/lexcal_cast.hpp>
// ...
std::string s = "1234";
int i = boost::lexical_cast<int>(s);
If you insist on using C, sscanf
can do this cleanly.
const char *s = "1234";
int i = -1;
if(sscanf(s, "%d", &i) == EOF)
{
//error
}
You can also use strtol
with the caveat that it requires a little thinking. Yes, it'll return zero for both strings evaluating to zero and for error, but it also has an (optional) parameter endptr
which will point to the next character after the numeric that's been converted:
const char *s = "1234";
const char *endPtr;
int i = strtol(s, &endPtr, 10);
if (*endPtr != NULL) {
//error
}

Mahmoud Al-Qudsi
- 28,357
- 12
- 85
- 125
-
Is that really best-practice? I expect there's a fair amount of overhead using a stringstream: creating the stream object, it creating a container for stored strings, adding the string (or probably a copy of it) to the stream, assembling the strings in the stream into a single string to feed into the wtoi processor and then finally parsing the number. Also how can you do this for non-base-10? – Rup May 21 '12 at 16:59
-
@rup feed the input to `std::hex` before `std::stringstream`, for example. – Mahmoud Al-Qudsi May 21 '12 at 17:05
-
Neat, hadn't seen that - but I still think it's wrong because of the unnecessary overhead. I found [this old answer](http://stackoverflow.com/a/6154614/243245) that warns against it (and lexical_cast) but more because of control. – Rup May 22 '12 at 08:23
-
1I'd say it's likely a case of premature optimization. If you're converting strings to integers, you're likely either reading user input or reading from files/streams. Worry about it only if your profiler says you need to. – Mahmoud Al-Qudsi May 22 '12 at 15:10