While strtod()
doesn't allow you to limit the string length, you can use sscanf()
with a maximum field width and an optional check for the number of characters consumed, like so:
#include <stdio.h>
double parseDouble(const char *str){
double val = 0;
int numCharsRead;
// Handle errors by setting or returning an error flag.
if(sscanf(str, "%3lf%n", &val, &numCharsRead) != 1){
puts("Failed to parse double!");
}
else if(numCharsRead != 3){
puts("Read less than three characters!");
}
return val;
}
int main(){
printf("%lf\n", parseDouble("1.3")); // 1.300000
printf("%lf\n", parseDouble("1.5999")); // 1.500000
printf("%lf\n", parseDouble(".391")); // 0.390000
printf("%lf\n", parseDouble(".3")); // Read less than three characters!\n0.300000
return 0;
}
sscanf(str, "%3lf%n", &val, &numCharsRead
is the important part: you specify a maximum width of 3, which means that sscanf()
will read up to 3 characters for that particular field, and also store the number of characters consumed by the end of the parse in numCharsRead
. You can then check that value if you care about reading exactly 3 characters every time; if you're fine with 3 or less, you can just use sscanf(str, "%3lf", &val)
. For reference, here's the documentation for width specifiers:
An optional decimal integer which specifies the maximum field width.
Reading of characters stops either when this maximum is reached or when a
nonmatching character is found, whichever happens first. Most conversions
discard ini‐ tial white space characters (the exceptions are noted below),
and these discarded characters don't count toward the maximum field width.
String input conversions store a terminating null byte ('\0') to mark the end
of the input; the maximum field width does not include this terminator.
"1.23" => 1.2
,"1234" => 123.0
&"0.09" => 0.0
– Earwitness