We're a community of 1076K IT Pros here for help, advice, solutions, professional growth and fun. Join us!
1,075,695 Members — Technology Publication meets Social Media

# Numeric Check for Decimal Values

Hi All,
I'm handling a code which is having signed decimal values(eg: -123.456)stored in a cheracter string.While performing numeric calculations on this field, need to check whether all digit is numeric.Can anyone help me.
NB: There is strict instruction to store these values in char string.Not double/float

7
Contributors
9
Replies
23 Hours
Discussion Span
8 Months Ago
Last Updated
10
Views
Remzz
Newbie Poster
2 posts since Aug 2012
Reputation Points: 0
Skill Endorsements: 0

Create a for-loop, that iterates through each character, and ensure their ASCII (assuming you are not working with international representations) value is numeric, a hyphen or a decimal. At the same time, make sure you're checking for a hyphen at the beginning only, and only one decimal.

You could also use a regular expression library, but it's trivial enough that I wouldn't bother.

nmaillet
Posting Pro
537 posts since Aug 2008
Reputation Points: 111
Skill Endorsements: 3

You can also use isdigit() library function and loop through the string to check whether thy are numeric or not.

np complete
Posting Whiz
385 posts since Sep 2010
Reputation Points: 18
Skill Endorsements: 0

Another approach is to use the `strtod(const char* nptr, char** endptr)` function. You pass the string containing the number, and the address to a char* which will be set by the function to the first non-numeric character. FWIW, `strtod()` [double] and `strtof()` [float] will also accept scientific notation, such as 1.254e25. This is the technique I usually use, although I also will utilize an algorithm that walks through the string to check each character in some specific (rare) circumstances where I need to validate a particular numeric format.

rubberman
Posting Maven
2,571 posts since Mar 2010
Reputation Points: 365
Skill Endorsements: 51

You could use `boost::lexical_cast` to try and convert the string to a number and catch the `boost::bad_lexical_cast` exception that's thrown if the conversion can't be done. This feels a bit weird though, as I generally try not to use exceptions for flow control. I guess you should wrap it in a function that catches the exception and returns `false`. You could also do additional validation in this function too, like checking it's actually decimal and not octal or hexadecimal or something.

ravenous
Practically a Master Poster
681 posts since Jul 2005
Reputation Points: 286
Skill Endorsements: 8

Another approach is to use the strtod(const char* nptr, char** endptr) function.

You could use boost::lexical_cast to try and convert the string to a number

I'm curious how these two approches actually test for valid values. Won't they both simply convert whatever it can to binary and stop when an invalid character is seen? The OP did say

need to check whether all digit is numeric.

WaltP
Posting Sage w/ dash of thyme
Team Colleague
11,404 posts since May 2006
Reputation Points: 3,421
Skill Endorsements: 36

I'm curious how these two approches actually test for valid values.

At least for strtod(), a combination of the return value and end pointer as the second argument can be used to validate the string. If conversion stopped before the end of the string, then it's not valid.

I'm not sure about the latest implementation of boost::lexical_cast, but originally it was based on a stringstream and you could test for error or eof status.

Of course, there might be a remaining issue if the OP wants to validate an arbitrary length value, because strtod() and boost::lexical cast are limited to the size of a double for the implementation.

deceptikon
Challenge Accepted
3,427 posts since Jan 2012
Reputation Points: 822
Skill Endorsements: 56

Ahh, OK. Thanks.

WaltP
Posting Sage w/ dash of thyme
Team Colleague
11,404 posts since May 2006
Reputation Points: 3,421
Skill Endorsements: 36

Won't they both simply convert whatever it can to binary and stop when an invalid character is seen?

`boost::lexical_cast` will throw `boost::bad_lexical_cast` if the string can't be fully converted to the kind of value that you specify. For example, the following prints "That's not a valid number!":

``````#include <iostream>
#include <string>

#include <boost/lexical_cast.hpp>

int main()
{
std::string str( "-1.23x2e2" );

try {
std::cout << boost::lexical_cast< double >( str ) << std::endl;
}
catch ( const boost::bad_lexical_cast& ) {
std::cout << "That's not a valid number!" << std::endl;
}

return 0;
}
``````

However, if you remove the `x` from the middle of `str` you will, correctly, see `-123.2`.

ravenous
Practically a Master Poster
681 posts since Jul 2005
Reputation Points: 286
Skill Endorsements: 8

Thanks a lot for the help.
I tried the below snippet and is working as expected.

``````int main ()
{
int rc;

char number[10] = "3.1415";
rc = ProcessCheckNumeric(number);

if (rc==0)
printf("\n Numeric \n");
else
printf("\n Non Numeric\n");

}

int ProcessCheckNumeric(char szTemp[])
{
int rc;
int cnt;
cnt=0;

if (szTemp[0]=='-' || szTemp[0]=='+')
{
for(int j=1;szTemp[j]!='\0';j++)
{
if (isdigit(szTemp[j]))
{
rc=0;
}
else if ((szTemp[j]=='.') && (cnt==0))
{
rc=0;
cnt++;
}
else
{
rc=1;
break;
}
}
return rc;
}
else
{
for(int j=0;szTemp[j]!='\0';j++)
{
if (isdigit(szTemp[j]))
{
rc=0;
}
else if ((szTemp[j]=='.') && (cnt==0))
{
rc=0;
cnt++;
}
else
{
rc=1;
break;
}
}
return rc;
}
}
``````
Remzz
Newbie Poster
2 posts since Aug 2012
Reputation Points: 0