Reputation: 357
I'm trying to use sscanf() to validate commandline input
I want only things like 1, 0.1, 0.111 to go through, not a12 12a or 1.2a
I tried
if (sscanf(input, "%f", &val) != 1) { // to check for 1 successful conversion
printf("invalid input");
}
but it seems like I'm letting invalid inputs go through as well.
Any advice?
Upvotes: 4
Views: 828
Reputation: 8705
When sscanf(input, "%f", &var)
encounters the input 12a
or 1.2a
, it stops at the invalid input part, leaving the remaining characters available for reading by a subsequent format code.
Consider that the following strings have invalid characters for floating point numbers following a valid number:
1.0 2.0
(a space)1.0, 2.0
(a comma)1.0a 2.0
(a letter)Spaces and commas look OK to our human parsing engine; the machine floating point parsing simply stops when an invalid character is found, whether it is a human acceptable space or comma, or an ugly letter.
If you want to ensure that a floating point number is not immediately followed by garbage, you could use something like:
n = sscanf(input, "%f%c", &var, &ch);
if (n == 1 ||
(n == 2 && (ch == ' ' || ch == ',' || ...))) {
// ...
}
Upvotes: 3
Reputation: 1121
sscanf
is not your friend, here. Even if you check the result to
ensure that you read one whole argument successfully, that doesn't
really guarantee that the input is valid in a meaningful sense.
Given input like:
1!!!1!oneone!
the %f
parsing will stop (but succeed) after reading the first 1
,
and leave the read pointer at the following !
. This may not be what
you consider "valid input".
If anything on the same line is to be considered garbage, then it gets
difficult, because scanf
doesn't distinguish between spaces and
newlines. Perhaps try something like this:
int main(int argc, char *argv[])
{
float val;
char c;
if (sscanf(argv[1],"%f%c",&val,&c)!=1)
{
printf("invalid input");
}
return 0;
}
now it will validate all commandline input if it's floating number input or not.
Upvotes: 1