Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to judge whether a string is a valid number

3 views
Skip to first unread message

fengxvhui

unread,
Jun 14, 2003, 4:02:25 AM6/14/03
to
Hello everyone!
I want to know how to judge whether a string is a valid
number. It is well known that a valid number has the
format as follows:
[whitespace] [sign] [digits] [.digits] [ {d | D | e | E }
[sign]digits]
and a string can consist of any characters.
Eager for your help, thanks a million.

fengxvhui

Johan Rosengren

unread,
Jun 14, 2003, 5:51:13 AM6/14/03
to
fengxvhui,

You might - for example - want to check sscanf. Note that this is a locale
aware function, which might not be appropriate at all times. Be aware that
the "well known valid number format" is incorrect - I, as a Swede, would not
write "thirty four and a half" as 34.5, but rather 34,5. Group separators
are also different. Now, locale sensitive functions will take this into
consideration, but imagine a kiosk application in an airport - am I
supposed to know the local rules for formatting numbers? A hand-rolled
parser with as much flexibility as the task demands might be in order - and
as group separators might be decimal separators as well, you'd have to do a
two-pass scan :-(

Johan Rosengren
Abstrakt Mekanik AB

"fengxvhui" <feng...@163.com> wrote in message
news:071101c3324b$4ab57d90$a301...@phx.gbl...

Robert A.

unread,
Jun 14, 2003, 10:40:25 AM6/14/03
to
Hi feng,

I just did this, I made a custom edit box that would only allow valid
numbers to be entered.

First check the string for anything except 0...9,-,. and 'E' or 'e if using
scientific notation; that's a quick weeding out process. Then you can check
if there are more than one decimal places (more than one period character),
also check the minus sign, make sure there is only one and if so it's the
first character (except for scientific notation, I didn't do that so I can't
give directions.)

It's not really that hard, you just have to be careful and play around with
it until you get it right.

I don't know if my version is fool-proof but it seems to work fine for me;
I'm sure someone programmed a more advanced version so try to look around if
you don't like the way I did it.

Also, if you can control the original input of the string you should do it
there, for example, if someone is entering a number via an edit box.

About the Swede, hmm, he's right. That's kinda strange writing 45.5 as 45,5
(with a comma), to me that looks like an X,Y coordinate, LOL.

Johan, do you like Opeth ? I love that band :o)


Joseph M. Newcomer

unread,
Jun 14, 2003, 1:09:05 PM6/14/03
to
There is a finite-state machine that does this in my "Validating Edit Control" on my MVP
Tips site.
joe

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Doug Harrison [MVP]

unread,
Jun 14, 2003, 1:08:56 PM6/14/03
to
fengxvhui wrote:

This is simple enough to write it out as a regex and convert it directly to
an FSM. However, the simplest approach is to use strtod, which also converts
the string to double and in the process validates whether or not the number
is representable as a double:

#include <errno.h>
#include <stdlib.h>

double
xstrtod(const char* p)
{
char* ep;
errno = 0;
double res = strtod(p, &ep);
// If *ep, then there is some trailing junk that couldn't
// be converted. If ep == p, then no conversion at all could
// be performed. If errno, then overflow/underflow occurred.
if (errno || *ep || ep == p)
throw "error"; // Just an example response
return res;
}

Note that this function allows leading but not trailing whitespace, and it
considers overflow/underflow errors. This one is a little more flexible, but
it puts more of the error handling burden on the caller:

#include <errno.h>
#include <stdlib.h>

bool
StrToDouble(const char* p, char*& ep, double& d)
{
errno = 0;
d = strtod(p, &ep);
return !(errno || ep == p);
}

This function eats leading whitespace, considers overflow/underflow errors,
and it returns a pointer to the character which stopped the scan, which is
useful for subsequent parsing. If it returns false, the caller can do the
following to determine why it failed:

if (ep == p)
no conversion possible;
else if (*ep is junk and we care)
handle error
else
{
assert(errno == ERANGE);
if (d)
overflow, d will be +/- HUGEVAL
else
underflow
}

P.S. If you want strtod to reflect the Windows locale, call
setlocale(LC_NUMERIC, "") or setlocale(LC_ALL, "").

--
Doug Harrison
Microsoft MVP - Visual C++

fengxvhui

unread,
Jun 15, 2003, 3:34:46 AM6/15/03
to
0 new messages