Reputation: 7766
I am trying to test if a string contains an integer by iterating through the entire string and outputting the integer. My method involves converting the string to c-string , atoi
the c-string and then testing if its an integer using isdigit
function. For some unknown reason, isdigit
function is returning false though it encounters a integer.
I need help resolving this issue
#include <iostream>
using namespace std;
#include <string>
int main()
{
string p = "[ab, e2cd]";
for (int k = 0; k < p.length(); k++)
{
if (isdigit(atoi(p.substr(k,1).c_str())) == true) //testing done here
{
cout << atoi(p.substr(k, 1).c_str());
}
}
}
Upvotes: 4
Views: 8043
Reputation: 22084
atoi
converts a cstring to a number. If the string is invalid, you wont know, because atoi
returns 0, which could also be the number in the string.
isdigit
Should be passed a character as an int and returns false
if it is not a digit character. So you are comparing apple with oranges.
Just iterate over the string and pass each character to isdigit()
and if this works, then you can use atoi
to convert it.
One pitfall can be though, that the string contains +
or -
as part of the number, and isdigit()
does not return true
in this case. There may be other characters as well being part of a valid number, but for simple integer values, this should suffice.
Upvotes: 2
Reputation: 263237
The behavior of isdigit
is fairly bizarre, for historical reasons.
It takes a character value, and tells you whether it's a decimal digit (one of '0'
, '1'
, ... '9'
) -- which means that applying it to the result of atoi()
rarely makes sense.
But the character value is represented not as a char
, but as an int
whose value is in the range of unsigned char
. Any other argument value (other than EOF
, which is typically -1
) causes undefined behavior. So if you want to test a char
value, you should cast it to unsigned char
; if plain char
is signed, omitting the cast risks undefined behavior.
And the result isn't a bool
. It's an int
whose value is 0 for a non-digit, and any arbitrary non-zero value for a digit. Do not compare the result for equality to true
. For that matter, don't compare any value that represents a condition for equality or inequality to false
or true
; it's already a condition, so just use it directly.
If c
is a char
, replace
if (isdigit(c) == true)
by
if (isdigit((unsigned char)c))
or
if (isdigit(static_cast<unsigned char>(c)))
Upvotes: 2
Reputation: 227390
isdigit
takes an int
with the value of a single character in your locale. It is OK to pass it an unsigned char
cast from a char
, and let the conversion to int
do its thing. Since string
contains chars
, you can use it's elements like this:
if ( static_cast<unsigned char>(isdigit(p[k])) ) { ....
Upvotes: 3