Question:
C typecasting issues : How to typecast float input from scanf() to integer variable?
1970-01-01 00:00:00 UTC
C typecasting issues : How to typecast float input from scanf() to integer variable?
Five answers:
charleston
2016-11-15 05:58:29 UTC
Typecast In C
?
2016-10-04 06:32:57 UTC
D and I just like the baptismal font at church. Oh wait you imply in variety That used to be Fount besides, LOL. Whatever is through default works for me. I marvel what they are saying approximately De Fault within the city dictionary?
?
2012-08-05 07:21:54 UTC
1) Is "float rate=25;" a valid statement?Is the type-conversion done here from int to float implicitly here or this statement may show an error?



This is valid statement in C as C is not a strongly typed language unlike Java. Automatic converions are acceptable.



2)What would you suggest is the best way to deal with situations when a float value might be inputted for an integer variable?Is typecasting the answer?And if yes, how to use it in scanf() or other input functions?



scanf will not take a float if you use %d format string. However, even if you use %f to read a value to a float variable, we can enter integer.



int a;

scanf("%d", (float *) &a );

printf("%d", a);

If we give input as 1278.22822 we get output as 1278



int a;

scanf("%d", &a );

printf("%d", a);

If we enter 1278.22382 we get runtime error
Randy
2012-08-05 06:41:46 UTC
It's probably best to treat all input as floats. Integer entries will be displayed as 2.0, 3.0 , etc and floats will be treated correctly as well.



#include



int main()

{

int i;

float num[3];



printf("Enter numbers\n");

for(i=0;i<=2;i++)

scanf("%f",&num[i]);

printf("The numbers are\n");

for(i=0;i<=2;i++)

printf("%f\n",num[i]);

}





And if you want the integer entries to be displayed as integers you could simply test the remainder for zero and cast the result as an integer with no loss of information.



Hope that helps,

-Randy



@Randy Can you tell me what is meant by "Test the remainder for zero"?Rest of your answer I understood but not that part



using modf something like:



for ( i=0; i <=2; i++)

{

int intpart;

double fractpart = modf (num[i] , &intpart);

if (fractpart == 0.0)

{

printf("%d\n",(int)num[i]);

}



else

{

printf("%f\n",num[i]);

}
Jonathan
2012-08-06 13:00:57 UTC
scanf() and printf() are declared with:

    int scanf(const char *, ...);

    int printf(const char *, ...);



The ... part of those prototypes above don't help C to know what the parameter types should be. So the "usual arithmetic conversions" take place, I think. See Section 6.5.2.2 of the 1999 C standard.



For example, if you supply a float parameter then C promotes it to a double. It does that no matter what you do. Assume you did this:

    double x= 45.2;

    printf("%f\n", (float) x);



The C compiler sees that x is double. But that you are casting it explicitly to a float. So the C compiler causes a function call (or writes out direct code if it knows how) to convert x from a double to a float with the associated truncation of precision and possible errors that can be generated. It then sees that the result is a float. But since printf()'s prototype doesn't supply a type for that parameter, C invokes the "usual arithmetic conversions" and converts the float BACK into a double, again. That double is what gets passed to printf().



This is why %f and %lf both operate on a double even though they look like they might do different things. That's true with printf... but not so with scanf because scanf takes pointers, not actual values. So scanf will actually do different things with %f and %lf (not guaranteed to be different as it depends on the architecture and compiler design choices.)



scanf() uses pointers, but it looks to the format specifier string to tell it what those pointers mean. Explicit casting of them doesn't change any of that. So:

    int num[3];

    scanf("%d",(float *)&num[0]);

    scanf("%d",(double *)&num[1]);

    scanf("%d",(void *)&num[2]);



Should all work the same on machines where all the pointers are of the same kind and size (usually the case on most machines, but not always.) That is because the C compiler is just supplying a pointer as the 2nd parameter. Converting those pointers into different types usually doesn't change the pointer's value. The [] binds more tightly that the cast. So the C compiler treats num[] as a unit, uses the & to generate an address to it, then casts it. But since the cast doesn't change the value, it just passes the same value regardless of the cast to the scanf() function. The scanf() function has no idea what machinations the C compiler went to, and doesn't really care. It looks at the format specifier to decide what the pointer means. So as long as the pointer ACTUALLY points to an int, regardless of what it was cast into beforehand, scanf() will do just fine.



For example,

#include

int main( void ) {

    int x[3];

        scanf( "%d %d %d", (int *) &x[0], (float *) &x[1], (double *) &x[2] );

        printf( "%d %d %d\n", x[0], x[1], x[2] );

    return 0;

}

works just fine. The main thing is that you don't mess up on the printf() part of it. Those specifiers MUST match what the usual arithmetic conversions produce.



None of that helps you, though, if you supply as a user the value 25.123 when scanf() is looking for a %d. scanf() doesn't swallow up whole decimal values when scanning for %d. It looks for integers. So the period (.) will stop it from scanning further if you used %d. If you want to accept floating point numbers with scanf() but only need integers, then you need to supply a %f or %lf AND a proper float or double receiver variable and THEN do a run time conversion to get your integer value. You CANNOT do all of that in one go with scanf() alone. For example, try the following:



#include

int main( void ) {

    int i, x[3];

    double y[3];

        scanf( "%lf %lf %lf", &y[0], &y[1], &y[2] );

        for ( i= 0; i < 3; ++i ) x[i]= (int) (y[i] + 0.5);

        printf( "%f %f %f\n", y[0], y[1], y[2] );

        printf( "%d %d %d\n", x[0], x[1], x[2] );

    return 0;

}



As far as:

#include

    float y= 25;

goes, there is no problem. The C compiler (before generating code) will actually convert 25 to 25.0 (as a double value, to start) and then observe that y is a float and do an internal (at compile time) conversion of the double value into a float value constant that is stored into the executable as a float constant. At run time, no conversions take place at all. It was all handled at compile time because 25 is a constant. Had it been a double variable or an int variable with a value that could not be known at compile time then there would need to be a run time conversion taking place and the C compiler would insert that code.


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...