0

I want to take two integers as input and output their sum. The code works fine when two integers are given as input. But, when I give a non-integer value as input for first value (say 2.3) and press enter, the program doesn't wait for the second input and produces a weird output.

Could you please tell me why is this happening?

#include <stdio.h>

int main()
{
    int a, b;
    scanf(" %d%d", &a, &b);

    int c = a +b;
    printf("%d\n", c);

    return 0;
}
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Nithin
  • 159
  • 4
  • 4
    What value does `scanf()` return? – Andrew Henle May 08 '17 at 10:02
  • Hint: [The value has a meaning](http://stackoverflow.com/questions/10469643/value-returned-by-scanf-function-in-c). And based on the value, you can know if your uninitialized variables still hold indeterminate values. – StoryTeller - Unslander Monica May 08 '17 at 10:03
  • scanf() returns the number of values read successfully. In your case when input is 2.3, it returns 1 as only 2 is read correctly. But when you input both numbers as integer, then it returns 2 as it will read both integers corectly. – GAURANG VYAS May 08 '17 at 10:06

5 Answers5

1

Given the input 2.3, the space in the format character causes any whitespace to be skipped (there is none), and the first %d causes a value of 2 to be read. The next character to be read will be the ., and that will remain in the buffer. scanf(), when handling the second %d will encounter that '.', deem that character is not part of an integral value, and terminate reading, again leaving the '.' in the stream to be read.

The net effect of scanf(" %d%d", &a, &b) is therefore to read 2 to a, and there is no change of b.

Unless your code does something to read the '.' (e.g. read it using the %c format), that . will continue to be in the stream, and every subsequent usage of %d will fail in the same way.

Your code is not checking the return value from scanf() but, if it did, would detect another consequence of the problem. The return value of scanf() will then be 1, indicating that one value (a) was successfully read. If both the integers a and b had been successfully read, the value 2 would be returned.

Since b is uninitialised in main(), accessing its value gives undefined behaviour, and scanf() doesn't change that fact. One possible consequence of undefined behaviour is the "weird output" you are seeing.

Peter
  • 35,646
  • 4
  • 32
  • 74
0

When you give scanf some input which it's unable to parse, it does not crash your program. Instead, it reports an error in its return value. Specifically, if you type 2.3, scanf will be able to read 2 into a, but will stop parsing when it meets dot.

Any variables which were not read may be left in the state they were. In your case, b may remain uninitialized. Reading from uninitialized variable is "undefined behavior" (I recommend googling what it is). In particular, your program is allowed to crash, format your hard drive or, well, output strangely looking garbage afterwards.

yeputons
  • 8,478
  • 34
  • 67
0

Use the return value of scanf

if (scanf("%d%d", &a, &b) != 2) exit(EXIT_FAILURE);
pmg
  • 106,608
  • 13
  • 126
  • 198
0

Just look at what scanf does -
Reads data from stdin and stores them according to the parameter format into the locations pointed by the additional arguments.

Moreover, scanf() returns the number of values read successfully.
You can see which values are being read properly by seeing the value returned by scanf(). In the case when user inputs 2.3 or any other such values( of the form integer.integer), scanf() returns 1. It means that only 2 is read successfully. In your case variable a is assigned value 2 while b has some garbage value. And when addition is performed then that garbage value is added to 2.

GAURANG VYAS
  • 689
  • 5
  • 16
0

Here is what the man page says about scanf()

RETURN VALUE
   On success, these functions return the number of input  items  success‐
   fully  matched  and  assigned;  this can be fewer than provided for, or
   even zero, in the event of an early matching failure.

   The value EOF is returned if the end of input is reached before  either
   the  first  successful conversion or a matching failure occurs.  EOF is
   also returned if a read error occurs, in which case the error indicator
   for the stream (see ferror(3)) is set, and errno is set to indicate the
   error.

this line:

scanf(" %d%d", &a, &b); 

should return 2. anything else indicates a problem.

suggest:

if( 2 != scanf( " %d %d", &a, &b ) )
{
    // handle error
}
user3629249
  • 16,402
  • 1
  • 16
  • 17