Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to check if a string can be a float in C?

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?

like image 307
Moonchild Avatar asked Aug 07 '17 19:08

Moonchild


2 Answers

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

like image 175
Sergey Kalinichenko Avatar answered Oct 27 '22 13:10

Sergey Kalinichenko


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);
    }
}
like image 10
Stephan Lechner Avatar answered Oct 27 '22 14:10

Stephan Lechner