# how can i prove a string does not contain a number ?

• 04-07-2004
blue_gene
how can i prove a string does not contain a number ?
how can i prove a string does not contain a number ?

for example,

string s1="1-23" // there is a negative sign inside....so s1 does not hold number

string s2 = "12 " // this also does not contain a number as ther is a space at last

string s3 = "123"; // this holds a number

for this example string s1,s2 does not contain a number but string s3 contain a number (i.e 123).

how can i prove ?

atoi() function wont be helpful in this case bcoz they dont care delimeters.

however how can solve this ?
• 04-07-2004
One way is char by char parsing of the string to be sure it has only what you want, where it is legal. Use of isdigit(), isalpha(), isalphanum() is quite helpful in writing this sort of function.
• 04-07-2004
hk_mp5kpdw
Using STL's count_if function in combination with isdigit to count how many non-digit characters there are (also some help from the not1 and ptr_fun function adapters):

Code:

```#include <string> #include <algorithm> #include <functional> #include <cctype> using namespace std; ... string str1 = "1-23"; string str2 = "12 "; string str3 = "123"; cout << "\"" << str1; if( count_if( str1.begin(), str1.end(), not1(ptr_fun(isdigit)) ) )     cout << "\" is not a number." << endl; else cout << "\" is a number." << endl; cout << "\"" << str2; if( count_if( str2.begin(), str2.end(), not1(ptr_fun(isdigit)) ) )     cout << "\" is not a number." << endl; else cout << "\" is a number." << endl; cout << "\"" << str3; if( count_if( str3.begin(), str3.end(), not1(ptr_fun(isdigit)) ) )     cout << "\" is not a number." << endl; else cout << "\" is a number." << endl;```
Should output:
Code:

```"1-23" is not a number. "12 " is not a number. "123" is a number.```
• 04-07-2004
Prelude
>Using STL's count_if function in combination with isdigit
"-123" is a number though. You would have to use something a little more selective than isdigit, but in this case count_if would really make things harder than a handrolled loop:
Code:

```bool isnumber ( string s ) {   if ( !isdigit ( s[0] ) && s[0] != '+' && s[0] != '-' )     return false;   for ( string::size_type i = 1; i < s.size(); i++ ) {     if ( !isdigit ( s[i] ) )       return false;   }   return true; }```
This way more detailed checking can be added without great difficulty.
• 04-07-2004
blue_gene
hi prelude, i feel your code will work but i am in trouble syntactically.i am not able to grasp it.

question 1.
you have written......

string::size_type i .....what is the meaning of size_type ? . i would have been happier if you wrote int i as you are inside a for loop.

you are using scope resolution operator here also .
probabily you have some reason to write this way. will you explain plz ? why you are not writing simply int i . in fact if i use int i it will not work.

question 2.> does size() is a member function of the string class? well, my MSDN library is not showing that type thing.

probabily you want to calculate the length of the string. so why not s.length() instead of s.size() ?

will you explain why my recomendation (i.e int i & s.length() )will not work ?

my problem lies the way you have written.

thanks
• 04-07-2004
skorman00
instead of using the STL, I would test each character's ascii value.

if the character >= '0' && the character <= '9' then you have a number. If you don't like doing character comparisons, I beleve the ascii value of 0 is 55.
• 04-07-2004
jverkoey
probably the most efficient way to do this would be to incorporate the char-by-char ascii value test, and also test if the first char is a '-' sign, so you can read in negative numbers, also.

Also, you could check to see if there is a '.' in the input, allowing you to have floating-point numbers, but make sure there's only ONE decimal :)
• 04-07-2004
Prelude
>if the character >= '0' && the character <= '9' then you have a number.
Which is easier to understand at a glance?
Code:

`if ( isdigit ( c ) )`
Code:

`if ( c >= '0' && c <= '9' )`
>If you don't like doing character comparisons, I beleve the ascii value of 0 is 55.
If you prefer to use ASCII codes instead of more portable character comparisons, you've got issues.

>what is the meaning of size_type ?
Usually size_t, but you can't be sure because the actual representation is dependent on the implementation of string. size_type is a portable type that will always work for indexing a string.

>i would have been happier if you wrote int i as you are inside a for loop
Your compiler wouldn't. Chances are good that you would get a signed/unsigned comparison warning because the size member function of string returns size_type, which is unsigned.

>probabily you have some reason to write this way.
I do indeed. size_type is defined inside of string, so you need to use the scope resolution operator to gain access to the name.

>why you are not writing simply int i
Because string::size_type is more correct.

>in fact if i use int i it will not work
It will work, you'll just get warnings.

>size() is a member function of the string class?
Yes.

>my MSDN library is not showing that type thing.
Get a real C++ reference then.

>so why not s.length() instead of s.size() ?
Because length returns size(). The two are equivalent, but common usage favors size().

>will you explain why my recomendation (i.e int i & s.length() )will not work ?
Define "will not work". I wrote code that was idiomatic and portable. Your way will work, so if you like it better then I'm not stopping you. Some people would prefer to use iterators instead of indices:
Code:

```for ( string::iterator i = s.begin(); i != s.end(); i++ ) {   if ( !isdigit ( *i ) )     return false; }```
There are often several correct ways to do something. If one method bothers you then you can use another.