9

In scanf() function I want to take only upto decimal values.Can we achieve it? For example for displaying upto two decimal places we use printf("%.2f",A) How can we do it for scanf() function.

user2864740
  • 60,010
  • 15
  • 145
  • 220
mani teja varma
  • 183
  • 1
  • 3
  • 12
  • Scanf uses almost the same format. –  Jan 25 '15 at 02:59
  • Why would you want to do that? – Iharob Al Asimi Jan 25 '15 at 03:03
  • I tried it. While trying to display the variable it displayed as 0.00000 – mani teja varma Jan 25 '15 at 03:04
  • 3
    Read the whole value, and print the 2 decimal places using `printf("%.2f\n", value);` – Iharob Al Asimi Jan 25 '15 at 03:06
  • There is no good reason to do this. – Zan Lynx Jan 25 '15 at 03:07
  • 1
    @ZanLynx There *is* a good reason - as evidenced by money (UI) fields that only accepts 2 decimal places for USD, for example. scanf - being a primitive stream reader - just doesn't fit the use-case and does not support the requested behavior. (And then there is the entire issue of relative precision / floats being non-fixed.. but that's almost secondary as there isn't even a way to limit the decimals if read as a string.) – user2864740 Jan 25 '15 at 03:07
  • 1
    @manitejavarma: Re: "While trying to display the variable it displayed as 0.00000": This statement betrays a very deep misunderstanding of what your variable actually *is* . . . you should really read up about floating-point numbers. `scanf` and `printf` do not do what you think. – ruakh Jan 25 '15 at 03:13
  • 1
    @user2864740: Either the money value is real money in which case it is an integer in cents, NOT float, or it is a calculated value in which case the more precision, the better. – Zan Lynx Jan 25 '15 at 03:37

4 Answers4

4

scanf() does not have a simple method to meet OP's goal.
Recommend using fgets() for input and then parse the string.

char buf[20];
fgets(buf, sizeof buf, stdin);  // Could add check for NULL here

To limit to 2 decimal places, code could read the number in parts: integer portion and fraction, then form the result:

long long ipart;
unsigned d[2];
int n;
if (sscanf(buf, "%lld.%1u%1u %n", &ipart, &d[0], &d[1], &n) != 3 || buf[n]) {
  Handle_InvalidInput();
}
double value = (d[0]*10 + d[1])/100.0;
value = ipart + ipart < 0 ? -value : value;

Even though this fulfills OP's quest, I do not think it solves OP's larger goal. So rather than limit input, read the input and then qualify it:

double value;
if (sscanf(buf, "%lf %n", &value, &n) != 1 || buf[n]) {
  Handle_InvalidInput();
}
double rounded_value = round(value * 100.0)/100.0;
if (rounded_value != value) {
  Handle_OverlyPreciseNumber(value, rounded_value);
}

Other more pedantic methods would inspect the string buf for ddd...ddd.dd syntax, etc. But the issue is clear: read the data and then qualify the data read. Do not attempt to restrict the input.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
3

You can't do that, you can make scanf() read a specific number of characters if you want like

float value;
scanf("%4f", &value);

and suppose the input is

43.23

it will read

43.2

but you can't specify precision.

It doesn't make sense, what you can do is

float value;
if (scanf("%f", &value) == 1)
    printf("%.2f\n", value);

after all, the precision is limited by the binary representation, so making it have only two decimal places is pointless since in arithmetic operations it might be rounded.

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
0

it is not possible to mention precision in scanf. You can however restrict the number of input characters like scanf("%4f",&a).

0
  1. include stdlib.h
  2. include math.h
  3. IF function pow from math.h fails to compile, must compile with gcc file.c -o file -lm
  4. TRY example :

Input : 13254.45488

Output: 13254.45

void main()
{

    int x,y,i ;
    int precision = 2 ; /*Insert precision here*/
    char a[precision] ;
    long double z,result ;

    printf( "Input : " );   
    scanf( "%d" , &x );

    for ( i = 0 ; i <= precision  ; i++ )
    {

        a[i] = getchar();

        if ( a[i] == 10 ) break;

    }
    
    a[0] = '0';
    a[i] = '\0';

    y = atoi(a);
    z = y / pow( 10 , i-1 );
    result = x ;

    if ( z != 0 ) result = result + z ;

    printf( "Output: " );   
    printf( "%.*Lf\n", i-1 , result );

}
Community
  • 1
  • 1
  • Code needs work. 1) `char a[precision] ;... for ( i = 0 ; i <= precision ; i++ ) { a[i] = getchar(); ...` is UB (buffer overrun). 2) Fails for negative numbers. 3) Fails when the whole number port is outside `int` range. 4) `if ( z != 0 )` is unnecessary. 5) fails when fractional input part is less than `precisions` digits. 6) minor issues with accepting input like `"123 456"` as 123.45 rather than 123 and leaving 456 for later. – chux - Reinstate Monica Oct 12 '17 at 16:15