Why was type checking not happening on second parameter and only on first parameter?

StackOverflow https://stackoverflow.com/questions/23521235

  •  17-07-2023
  •  | 
  •  

Question

In the below code when I entered 'a' value as 3.4(i.e. float) it is giving me answer garbage value without even allowing me to enter the 'b' value and when I given 'a' value as 3 and 'b' value as 2.3(i.e. float) it is accepted and giving me answer 5 not a garbage.

My question is why type checking was not happening on second parameter ;why only on first parameter?

more clearly if I give 3,3.5 code is working but why cant i give input as 3.5,3 ?

int sum(int k,int l)
{
  int s= k+l;
  return s;
}

void main()
{
  int a,b,k;
  printf("enter the numbers");
  scanf("%d",&a);
  scanf("%d",&b);
  k= sum(a,b);
  printf("the value of sum is %d", k);
}

PS: I saw this question on quora. I was not happy with the answers provided there. I thought SO is the best place to ask this question.

Was it helpful?

Solution

Type checking is not the issue in your program. Type checking happens at compilation time; the behavior you're seeing occurs at run time. There is an issue with compile-time type checking for printf, scanf, and similar functions, which I discuss below, but that doesn't apply to your program, which does pass arguments of the correct type to both scanf and printf. Nevertheless, I'll discuss that issue below (because I wrote about it before I read your question closely enough).

You call scanf twice to (attempt to) read two int values. The input is 3.4, which would be valid input for a float or double. So what does scanf do with this?

scanf with a "%d" format reads input formatted like an optionally signed integer literal, stopping when it sees anything that doesn't match that format. So the first scanf reads just the 3 and stops at the .. It doesn't consider that the . might be a decimal point because you didn't ask it to read a floating-point value. The . isn't an error, it's just the end of the input that scanf("%d", ...) is looking for.

The second scanf attempts to read another int value, but now the first character in the input stream is the ., which cannot be part of a valid integer literal, so it fails. (Examining the return value of scanf would tell you this; it returns the number of items successfully scanned.)

You should always check the results returned by input functions and write code to handle failure (even if you handle it just by aborting the program with an error message).

A safer way to read numeric input is to read an entire line at a time using fgets(), and then parse the line in memory using sscanf. That can have problems too, but it won't leave invalid input characters waiting to be read by later calls (unless you have a very long input line). Read the documentation of fgets and sscanf for more information -- and again, always check the results they return so you can detect input errors.


Both printf and scanf are variadic functions, meaning that they can accept a variable number and types of arguments.

The declaration of printf, for example, is:

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

This means that the first argument in a call to printf is checked against the parameter type, but the zero or more following arguments are not checked at compile time. This gives you tremendous flexibility, but at the cost of compile=time checking. It's almost entirely up to you to ensure that all the following arguments are of the types specified by the format string. If you pass an argument of the wrong type (e.g., printf("%d\n", 1.5)), you won't necessarily get an error message; instead, the behavior is undefined.

scanf is similar, but with different semantics for the format string (most arguments are pointers rather than values to be printed).

Some compilers (gcc in particular) will do additional checking for you if the format string is a string literal, but this is not required and other compilers might not do this.


Incidentally, the code you posted is missing the required

#include <stdio.h>

and void main() should be int main(void). If you're using a book or tutorial that suggests using void main(), it was probably written by someone who doesn't know the C language very well. Find a better one.

OTHER TIPS

When scanf encounters a double for variable 'a' as you noted 3.4. It reads 3 as the integer and stops at the decimal. the .4 will then be read as a double on the next call. It works when the second input is a float because it drops the decimal and is not called again thus ignoring the remaining decimals. As noted in the comments, read about scanf and make some changes to the code.

I think you should add "getchar()" after scanf method,when you press enter,the '/n' will give next parameter. it's just my point.

void main()
{
  int a,b,k;
  printf("enter the numbers");
  scanf("%d",&a);

  getchar();/* the /n is last in stdin*/

  scanf("%d",&b);
  k= sum(a,b);
  printf("the value of sum is %d", k);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top