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.
Your co-operation greatly appreciated.
NB: There is strict instruction to store these values in char string.Not double/float

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.

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

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.

Edited 4 Years Ago by rubberman

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.

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.

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.

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.

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;   
  }
}
This article has been dead for over six months. Start a new discussion instead.