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(co nst 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(cons t 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(buff er1) && validinteger(bu ffer2);
}
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;
}
--
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(co nst 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(cons t 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(buff er1) && validinteger(bu ffer2);
}
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;
}
--
Comment