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...
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 [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
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++