Checking if it can be an int is easy enough -- just check that every digit is between '0'
and '9'
. But a float is harder. I found this, but none of the answers really work. Consider this code snippet, based on the top (accepted) answer:
float f;
int ret = sscanf("5.23.fkdj", "%f", &f);
printf("%d", ret);
1
will be printed.
Another answer suggested using strpbrk
, to check if certain illegal characters are present, but that wouldn't work either because 5fin7
wouldn't be legal, but inf
would.
Yet another answer suggested checking the output of strtod. But consider this:
char *number = "5.53 garbanzo beans"
char *foo;
strtod(number, &foo);
printf("%d", isspace(*foo) || *foo == '\0'));
It'll print 1
. But I don't want to remove the isspace
call entirely, because " 5.53 "
should be a valid number.
Is there a good, elegant, idiomatic way to do what I'm trying to do?
The first answer should work if you combine it with %n
, which is the number of characters read:
int len;
float ignore;
char *str = "5.23.fkdj";
int ret = sscanf(str, "%f %n", &ignore, &len);
printf("%d", ret==1 && !str[len]);
!str[len]
expression will be false if the string contains characters not included in the float
. Also note space after %f
to address trailing spaces.
Demo
You could check if - after having read a value using strtod
- the remainder consists solely of white spaces. Function strspn
can help here, and you can even define "your personal set of white spaces" to consider:
int main() {
char *number = "5.53 garbanzo beans";
char *foo;
double d = strtod(number, &foo);
if (foo == number) {
printf("invalid number.");
}
else if (foo[strspn(foo, " \t\r\n")] != '\0') {
printf("invalid (non-white-space) trailing characters.");
}
else {
printf("valid number: %lf", d);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With