OP does not specify how to handle an input like "9.00". I assume OP would like to see "9.00" printed and not "9" as the input gave a tenths and hundredths place.
One needs to read the number first as a string so it can be later assessed for precision. The number and its precision need separate variables. A structure would be recommended as in @bgamlath.
Parse the string with sscanf()
or atof()
.
Parse the string for the location of '.'
.
int VikasRead(float *value, int *precision) {
char buf[100];
*precision = 0;
if (fgets(buf, sizeof buf, stdin) == NULL) return EOF;
int end;
int retval = sscanf(buf, "%f%n", value, &end);
char * dp = strchr(buf, '.');
if (dp != NULL && retval == 1) {
*precision = &buf[end] - dp;
}
return retval;
}
int VikasWrite(float value, int precision) {
int retval;
if (precision > 1) {
// Note: printf("%.*f\n", 0, value) is UB.
retval = printf("%.*f\n", precision - 1, value); // 1.234
}
else if (precision == 0) {;
retval = printf("%.0f\n", value); // 123
}
else {
retval = printf("%#.0f\n", value); // 123.
}
return retval;
}
void VikasTest(void) {
float value;
int precision;
while (VikasRead(&value, &precision) == 1) {
VikasWrite(value, precision);
}
}
Exponential inputs like 1.23e56
complicates the process but the approach is still the same. Need to additionally look for an 'e'
or 'E'
.
Some locales use a ','
as a decimal point further complicating matters.