In need for testing if a string is a number which could be a double or integer, I wrote a simple skeleton, which parses a string like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[])
{
char* to_convert = argv[1];
char* p = NULL;
errno = 0;
long val = strtol(argv[1], &p, 0);
if (errno != 0)
return 1;// conversion failed (EINVAL, ERANGE)
if (to_convert == p){
// conversion to int failed (no characters consumed)
double val2 = strtod(p, &p);
if (*p){
printf("Not a number!\n");
return 1;
}
printf("Double %lf\n" , val2);
return 0;
}
if (*p != 0){
// conversion to int failed (trailing data)
double val2 = strtod(argv[1], &p);
if (*p){
printf("Not a number!\n");
return 1;
}
printf("Double %lf\n" , val2);
return 0;
}
printf("Int %ld\n" , val);
return 0;
}
/*
$ ./a.out 123
Int 123
$ ./a.out -123
Int -123
$ ./a.out 31.1
Double 31.100000
$ ./a.out -231
Int -231
$ ./a.out NaN
Double nan
$ ./a.out -Nan
Double nan
$ ./a.out -INF
Double -inf
$ ./a.out INF
Double inf
$ ./a.out 12.3
Double 12.300000
$ ./a.out -12,3 # Although some european localels (like German, would consider this a number)
Not a number!
$ ./a.out -12.3
Double -12.300000
$ ./a.out foo
Not a number!
*/
I would like to know if this could be done better, without iterating on all the characters like here.
- Is there any case I didn't think of which breaks this code?
- or causes undefined behaviour (except numbers larger than long on my architechture)?
Another thing is the problem with decimal seperator. How do you convert a number where the decimal separator is comma instead of a point like in the German language? This would be a nice to have, but not a must.
For example, my code says 12,3
is not a number, for a German person this would be a number (12.3
for English speakers).
if (sscanf(data, "%*lf%n", &count) == 1 && data[count] == '\0') { /* Its a Number */ }
. Also scanf is uses the local local for number scanning. ; – Loki Astari Dec 4 '14 at 19:12long float
ie a double. "%*lf" is the same but the star means don't store. "%n" means count the number of characters that have been read from the input. – Loki Astari Dec 8 '14 at 22:16