473,396 Members | 1,996 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Checking for valid number syntax

The following three functions check whether a given string
represents a valid number. They require that the entire string
represent
a number, unlike strtod which accepts strings like
"99rQF" and returns 99. Is there a way to make strtod and friends
behave like the functions below? Is there some room for improvement
of the functions below from the point of view of speed of execution?
The code below should be compilable.

Thanks,

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int validinteger(const char* s)
{
/* input string s may have leading or trailing blanks */
const int false = 0;
size_t n = 0, N = strlen(s);
int state = 0;
int c;
while (n < N)
{
c = s[n];
switch (state)
{
case 0:
if (isdigit(c))
state = 1;
else if (c == '-' || c == '+')
state = 2;
else if (!isspace(c))
return false;
break;
case 1:
if (isspace(c))
state = 3;
else if (!isdigit(c))
return false;
break;
case 2:
if (isdigit(c))
state = 4;
else
return false;
break;
case 3:
if (!isspace(c))
return false;
break;
case 4:
if (isspace(c))
state = 3;
else if (!isdigit(c))
return false;
break;
}
++n;
}
return state == 1 || state == 3 || state == 4;
}

int validfloat(const char* s)
{
/* input string s may have leading or trailing blanks */
const int false = 0;
size_t n = 0, N = strlen(s);
int state = 0;
int c;
while (n < N)
{
c = s[n];
switch (state)
{
case 0:
if (isdigit(c))
state = 1;
else if (c == '-' || c == '+')
state = 2;
else if (c == '.')
state = 5;
else if (!isspace(c))
return false;
break;
case 1:
if (isspace(c))
state = 6;
else if (c == '.')
state = 3;
else if (!isdigit(c))
return false;
break;
case 2:
if (isdigit(c))
state = 1;
else if (c == '.')
state = 5;
else
return false;
break;
case 3:
if (isdigit(c))
state = 4;
else if (isspace(c))
state = 6;
else
return false;
break;
case 4:
if (isspace(c))
state = 6;
else if (!isdigit(c))
return false;
break;
case 5:
if (isdigit(c))
state = 4;
else
return false;
break;
case 6:
if (!isspace(c))
return false;
break;
}
++n;
}
return state == 1 || state == 3 || state == 4 || state == 6;
}

int validreal(const char* s)
{
/* input string may have leading or trailing blanks */
int k, c;
char buffer1[64], buffer2[64];
const char *n;
char* p = strchr(s, 'e');
char* q = NULL;
if (p == NULL)
q = strchr(s, 'E');

if (p == NULL && q == NULL)
return validfloat(s);
if (p != NULL)
c = *p;
else if (q != NULL)
c = *q;

n = &s[0];
k = 0;
while (*n != c)
{
buffer1[k] = *n;
++k;
++n;
}
buffer1[k] = '\0';
++n;
k = 0;
while (*n != '\0')
{
buffer2[k] = *n;
++k;
++n;
}
buffer2[k] = '\0';
return validfloat(buffer1) && validinteger(buffer2);
}

int main (int argc, char** argv)
{
int n;
int x;
for (n = 1; n < argc; ++n)
{
x = validreal(argv[n]);
printf("%12s %10d \n", argv[n], x);
}
return 0;
}

--

Dec 20 '06 #1
8 2054
"Count Dracula" <Le**********@navy.milwrites:
The following three functions check whether a given string
represents a valid number. They require that the entire string
represent
a number, unlike strtod which accepts strings like
"99rQF" and returns 99.
You can always do the following:

#v+
#include <stdlib.h>
/* ... *

int validint(const char *str, long *val) {
if (!str || !*str) {
return 0;
} else {
char *end;
long v = strtol(str, &end, 0);
if (*end) {
return 0;
} else {
*val = v;
return 1;
}
}
}

int validdouble(const char *str, double *val) {
if (!str || !*str) {
return 0;
} else {
char *end;
double v = strtod(str, &end);
if (*end) {
return 0;
} else {
*val = v;
return 1;
}
}
}
--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
Dec 20 '06 #2

"Michal Nazarewicz" <mi****@tlen.plwrote in message
news:87************@erwin.mina86.com...
"Count Dracula" <Le**********@navy.milwrites:
>The following three functions check whether a given string
represents a valid number. They require that the entire string
represent
a number, unlike strtod which accepts strings like
"99rQF" and returns 99.

You can always do the following:

#v+
#include <stdlib.h>
/* ... *

int validint(const char *str, long *val) {
if (!str || !*str) {
return 0;
} else {
char *end;
long v = strtol(str, &end, 0);
if (*end) {
return 0;
} else {
*val = v;
return 1;
}
}
}

int validdouble(const char *str, double *val) {
if (!str || !*str) {
return 0;
} else {
char *end;
double v = strtod(str, &end);
if (*end) {
return 0;
} else {
*val = v;
return 1;
}
}
}

Why not return:
-1 on success,
0 for null or empty string
end-str for bad format

This gives the index of the offending character.
--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Software Reuse Project
..
Dec 20 '06 #3
>"Count Dracula" <Le**********@navy.milwrites:
>>The following three functions check whether a given string
represents a valid number. They require that the entire string
represent
a number, unlike strtod which accepts strings like
"99rQF" and returns 99.
"Michal Nazarewicz" <mi****@tlen.plwrote in message
news:87************@erwin.mina86.com...
>You can always do the following:
[code removed]

"Fred Kleinschmidt" <fr******************@boeing.comwrites:
Why not return:
-1 on success,
0 for null or empty string
end-str for bad format

This gives the index of the offending character.
But of course - if you'd like to. :) My point is that there's no need
to write those functions from stretch but strtol() and strtod() can be
used.

#v+
#include <stdlib.h>

long parseint(const char *str, long *val) {
if (!str || !*str) {
return 0;
} else {
char *end;
long v = strtol(str, &end, 0);
if (*end) return end - str;
if (val) *val = v;
return -1;
}
}
#v-
--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
Dec 21 '06 #4
On Thu, 21 Dec 2006 11:42:58 +0100, Michal Nazarewicz <mi****@tlen.plwrote:
>>"Count Dracula" <Le**********@navy.milwrites:
The following three functions check whether a given string
represents a valid number. They require that the entire string
represent
a number, unlike strtod which accepts strings like
"99rQF" and returns 99.
>"Michal Nazarewicz" <mi****@tlen.plwrote in message
news:87************@erwin.mina86.com...
>>You can always do the following:
[code removed]

"Fred Kleinschmidt" <fr******************@boeing.comwrites:
>Why not return:
-1 on success,
0 for null or empty string
end-str for bad format

This gives the index of the offending character.

But of course - if you'd like to. :) My point is that there's no need
to write those functions from stretch but strtol() and strtod() can be
used.
Also worth to keep in mind: both strtol() and strtod() accept a much wider
syntax than the original poster's code (hexadecimal, "NaN", etc etc). And he
accepted one thing those functions don't: leading/trailing whitespace.

We had a long discussion about this recently in
se.dator.programmering.diverse, but of course that's in Swedish ...

But yes, he's probably better off with the standard functions.

/Jorgen

--
// Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
\X/ snipabacken.dyndns.org R'lyeh wgah'nagl fhtagn!
Dec 21 '06 #5
2006-12-21 <sl***********************@frailea.sa.invalid>,
Jorgen Grahn wrote:
On Thu, 21 Dec 2006 11:42:58 +0100, Michal Nazarewicz <mi****@tlen.plwrote:
>>>"Count Dracula" <Le**********@navy.milwrites:
The following three functions check whether a given string
represents a valid number. They require that the entire string
represent
a number, unlike strtod which accepts strings like
"99rQF" and returns 99.
>>"Michal Nazarewicz" <mi****@tlen.plwrote in message
news:87************@erwin.mina86.com...
You can always do the following:
[code removed]

"Fred Kleinschmidt" <fr******************@boeing.comwrites:
>>Why not return:
-1 on success,
0 for null or empty string
end-str for bad format

This gives the index of the offending character.

But of course - if you'd like to. :) My point is that there's no need
to write those functions from stretch but strtol() and strtod() can be
used.

Also worth to keep in mind: both strtol() and strtod() accept a much wider
syntax than the original poster's code (hexadecimal, "NaN", etc etc). And he
accepted one thing those functions don't: leading/trailing whitespace.
In what way do those functions reject trailing whitespace in the sense
that they can be said to accept trailing "rQF"?
Dec 21 '06 #6
Jorgen Grahn <gr********@snipabacken.dyndns.orgwrites:
Also worth to keep in mind: both strtol() and strtod() accept a much wider
syntax than the original poster's code (hexadecimal, "NaN", etc etc). And he
accepted one thing those functions don't: leading/trailing whitespace.
strtol and strtod can both successfully convert strings that
contain leading and trailing white-space characters.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Dec 21 '06 #7

Ben Pfaff wrote:
(in his sig)
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Is that an ascii thing? I get

KvTUbCPQVKIVeifNHJRMZhj

as output on my system (ebcdic).

Dec 21 '06 #8
"Jalapeno" <ja*******@mac.comwrites:
Ben Pfaff wrote:
(in his sig)
>int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}

Is that an ascii thing?
No.
I get

KvTUbCPQVKIVeifNHJRMZhj

as output on my system (ebcdic).
Perhaps you cut and pasted it incorrectly, e.g. by omitting the
space at the beginning of the second line.
--
"...deficient support can be a virtue.
It keeps the amateurs off."
--Bjarne Stroustrup
Dec 21 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: - ions | last post by:
I have created a JComboBox with its Items as a list of "M" numbers ie. M1,M2,M3.......throgh too M110 (thes are the messier objects, a catolouge of deep sky objects) the user selects of of these...
6
by: Jeff Duffy | last post by:
Hi all. I've been wondering why python itself doesn't provide a switch to check a file for valid syntax. I know that you can currently call python -c "import py_compile;...
4
by: romek chronowski | last post by:
Hi I'm looking for a code in c or c++ that chcecks math syntax e.g it should check that sin(x+2) is valid syntax but sin(x-+y) or sin((x) is invalid .Thanks in advance (it is very important to me)
5
by: William Payne | last post by:
Hello, I am in the process of converting a C++ program to a C program. The user of the program is supposed to supply an integer on the command line and in the C++ version of the program I was using...
1
by: Karim Nassar | last post by:
I am writing functions and I find it curious that CREATE FUNCTION does not do syntax checking. Example: test=# CREATE FUNCTION foo(INTEGER) RETURNS BOOLEAN test-# AS 'this is total crap'...
10
by: Fredrik Tolf | last post by:
If I have a variable which points to a function, can I check if certain argument list matches what the function wants before or when calling it? Currently, I'm trying to catch a TypeError when...
15
by: H. | last post by:
What's the easiest way to check if an argument entered at the command line is a number? I know that one way would be to treat the argument as a character string, and then manually check each...
42
by: =?Utf-8?B?UGxheWE=?= | last post by:
I have an if statement that isn't working correctly and I was wondering how I check for a blank string. My Code Example if me.fieldname(arrayIndex) = "" then ----- end if When I do this and...
125
by: jacob navia | last post by:
We hear very often in this discussion group that bounds checking, or safety tests are too expensive to be used in C. Several researchers of UCSD have published an interesting paper about this...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.