3

Possible Duplicate:
How to parse a string to an int in C++?

There are numerous ways to convert string to int in C++03. The best I have found so far is this:

string text;
cin>>text;
int converted;

if ( !(istringstream(text) >> converted) ){
    cout<<"conversion failed\n";
}
cout<<"the converted string is "<<converted;

The problem with this solution is that it accepts "12monkeys" and converts it to 12 without hesitation. Is there some simple way to check this and output "conversion failed" in this case?

Just to note I have tried atoi(),atol() and strtol() but the fact that it returns 0 if it fails is futile. How am I supposed to know if the string was not "0"? There is no range check as well (except strtol()). Not mentioning the "12monkeys" problem is present there as well.

Community
  • 1
  • 1
Slazer
  • 4,750
  • 7
  • 33
  • 60
  • I can not use boost unfortunately, so I can't use C++11. I would like to find the most elegant and simplest solution in C++03. – Slazer Nov 07 '12 at 21:40
  • 1
    You can't use boost, **so** you can't use C++11? That doesn't make much sense. Boost works with C++03, or did you mean to say and? – chris Nov 07 '12 at 21:41
  • 3
    Have you gone through the [answer to a very similar question](http://stackoverflow.com/questions/194465/how-to-parse-a-string-to-an-int-in-c). It addresses your problem in detail. – vvnraman Nov 07 '12 at 21:42
  • If you can't use `boost::lexical_cast` then roll your own, like I did [here](http://stackoverflow.com/a/10586761/8747). – Robᵩ Nov 07 '12 at 21:42
  • @chris Sorry, I was not clear. I can not use boost. I can not use C++11. I must use C++03 only. – Slazer Nov 07 '12 at 21:44
  • 1
    To solve the problem with "12monkeys" input, see [here](http://stackoverflow.com/questions/13274462/how-do-i-check-that-stream-extraction-has-consumed-all-input/13274533#13274533) – jrok Nov 07 '12 at 21:45
  • 1
    "strtol() but the fact that it returns 0 if it fails is futile. How am I supposed to know..." rtfm: man strtol. Or read the answer wnraman has linked. – Sebastian Nov 07 '12 at 22:09
  • @wnraman I have just read the thread. Although Dan Moulding does not like the stringstream way, I have not found a reason against it unless I need to distinguish the over/underflow from inconvertible string, or unless I need to use base other than 10. – Slazer Nov 07 '12 at 22:50
  • @Sebastian Sorry I dont get it. The cppreference.com says "if no conversion can be performed, ​0​ is returned". Is there something else that indicates the error? Afaik errno is set to ERANGE only if there is range problem, not conversion problem. – Slazer Nov 07 '12 at 23:08

2 Answers2

2
const char *string = "12monkeys";
char *end;
long value = std::strtol(string, &end, 10);
if (end == string)
    std::cout << "No number found\n";
else if (*end != '\0')
    std::cout << "Extra characters on end.\n";
Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • Thanks I finally see how to use it. Just make sure to change "const char *end" to "char *end" for it to compile. – Slazer Nov 07 '12 at 23:22
  • @user1459339 - `char *end` is, indeed correct. Sigh. Fixed. It's one we missed; calling `strtol` turns a `const char*` into a modifiable `char*`. – Pete Becker Nov 08 '12 at 01:18
1

You can check for eof explicitly:

string text;
cin>>text;
int converted;

istringstream iss(text);
if ( !(iss >> converted) ){
    cout<<"conversion failed\n";
}
if( iss.get() != std::stringstream::traits_type::eof() ) {
    cout<<"cocnversion failed\n";
}
cout<<"the converted string is "<<converted;
Robᵩ
  • 163,533
  • 20
  • 239
  • 308