Check If A Value Is Numeric

Pages: 12
May 8, 2011 at 7:54pm
Hi
How can I check if a value is numeric or not?
for example:
user pass some values in main program via command line,all these parameters must be numeric,so I have to make sure that value is numeric or not.
I did not find any function for this checking.

Thanks for any help or guidance
May 8, 2011 at 8:06pm
closed account (zwA4jE8b)
every character has an integer representation. So check each element of the parameter against the proper int.

or you could just use isdigit()
May 8, 2011 at 10:22pm
The way to check is... try to convert it to a number.
Here is a function that may prove useful to you:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <sstream>
#include <string>

double string2double( const std::string& a )
  {
  // Convert a string representation of a number into a floating point value.
  // Throws an int if the string contains anything but whitespace and a valid
  // numeric representation.
  //
  double result;
  std::string s( a );

  // Get rid of any trailing whitespace
  s.erase( s.find_last_not_of( " \f\n\r\t\v" ) + 1 );

  // Read it into the target type
  std::istringstream ss( s );
  ss >> result;

  // Check to see that there is nothing left over
  if (!ss.eof())
    throw 1;

  return result;
  }

You can use this with your command-line arguments...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;

int main( int argc, char** argv )
  {
  vector <double> nargs;

  if (argc > 1)
  try
    {
    transform( argv + 1, argv + argc, back_inserter( nargs ), ptr_fun( string2double ) );
    }
  catch (int)
    {
    cerr << "The command line arguments must all be numbers!\n";
    return 1;
    }

  for (size_t n = 0; n < nargs.size(); n++)
    cout << n << ": " << nargs[ n ] << endl;

  return 0;
  }
May 8, 2011 at 10:36pm
I like Duoas' function. I would make that a template so it converts to int, double, float, etc. and I would change the parameter: std::string a. This way the function receives a copy of the string and line 11 becomes unnecessary.
May 8, 2011 at 10:59pm
The template is unnecessary -- a double will automatically convert to an int.
However, changing the argument type will break it, as it needs to have the const char* to string capability, and the generated strings are temporaries.
May 9, 2011 at 3:44am
a double will automatically convert to an int.
Maybe that is a problem (it will not throw up)

Isn't line 14 (and 11) superfluous? Shouldn't the insertion operator take care of that?
May 9, 2011 at 7:40pm
Isn't line 14 (and 11) superfluous? Shouldn't the insertion operator take care of that?

No. What if the user types "12abc" as a number?

See more at http://www.cplusplus.com/forum/beginner/13044/#msg62827
May 10, 2011 at 2:04am
What if the user types "12abc" as a number?
20
21
22
  // Check to see that there is nothing left over
  if (!ss.eof()) //<---
    throw 1;


I'm asking about
13
14
  // Get rid of any trailing whitespace
  s.erase( s.find_last_not_of( " \f\n\r\t\v" ) + 1 );
Ok, it's for accepting input like "42 "
May 10, 2011 at 3:22am
try to go through each digit of the text entered and used the isdigit() function (in the cctype header) as creativemfs pointed out. something like this should work fine
1
2
3
4
5
6
7
8
9
char stuff[10];
cin.getline(stuff, 10, '\n');
for (int i = 0; i < strlen(stuff); i++)
{
	if (isdigit(stuff[i])
		continue;
	else
		return false;
}
May 10, 2011 at 8:10pm
@ne555
You cannot hack out pieces of an algorithm and expect it to work properly.
Line 21 will fail if line 14 is missing -- even if the user only gives the string "42     " as input.

The algorithm assumes the following:

7
8
  // Throws an int if the string contains anything but whitespace and a valid
  // numeric representation. 

That is, the string must contain a valid number, and may also have leading and trailing whitespace. If it contains anything else, it fails.

If you change the algorithm then its behavior will also change.

@ascii
"-2.3" is a number. (And ".4.9-7" is not.) Likewise, "6.02e23" is a number.
May 10, 2011 at 8:40pm
Duoas, I presume you are an engineer? I see you quoting the Avogadro constant there, although not very precise, hehe. 6.022045e23 is how I remember it. :-)
May 10, 2011 at 10:00pm
Heh, no, just a hobbyist.
May 10, 2011 at 10:28pm
damn i just got pwned. in one of my more recent programs which i was basing my code off of it had support for a - symbol so negatives werent a problem, but its true that scientific notation wouldnt be recognized. anyhow 6.02e23 would be far too large to for an int wouldnt it?
May 10, 2011 at 10:51pm
Yes, too big, but still: 4e3 = 4000.
May 10, 2011 at 11:36pm
yeah i realize that, but generally someone will write out 4000 not 4e3. when you get to the point that you need to be using scientific notation youll probably be dealing with numbers out of the range of an int.
May 10, 2011 at 11:47pm
@Duoas: I should read the comments more carefully. Sorry about that.
@webJose: http://www.smbc-comics.com/index.php?db=comics&id=1777 xd.
May 11, 2011 at 12:37am
hehe, I guess I am a science fan then. Or used to be. I used to know a LOT more constants.

R (ideal gas constant) = 8.1314151 and the units I don't remember.
pi = 3.14159265359

.....

And that's it! LOL! I thought I still remembered some 5 or 6! I'm down to just 3. :-(
May 13, 2011 at 6:30pm
Hi again

Thanks a lot for your attention and good reply :):)
for long digit (ex. 12389770982703948750982734), what function can I use to convert to digit?

Thanks in advance
May 13, 2011 at 9:45pm
The value "12389770982703948750982734" is too large for a native integer type (say, a 64-bit integer -- you'd need at least an 84-bit integer).

To use huge values you'll need a bignum library.
May 14, 2011 at 10:15pm
to store that youll probably need a 64 bit unsigned integer
 
unsigned long long  number = 12389770982703948750982734;
Pages: 12