2

I've read similar questions and answers for code in C++ and just wanted to confirm my understanding.

For the C code below;

#include <stdio.h>

int main(void){

    int a, b, c, d; 
    a = scanf("%d%d%d", &b, &c, &d); 
    printf("Number of values read: %d\n", a); 
    printf("Values read: %d %d %d", b, c, d); 

return 0;
}

If input is 0 A 0,

My output is;

Number of values read: 1
Values read: 0 0 4200544

Is the following explanation correct? scanf expects data type int but gets char as input. Thus, it stops reading and returns a value of 0.

Only 1 value was accurately given as input, so number of values read: 1

2nd int is assigned value 0. The last int var is unassigned, so when printed, it returns garbage values.

Is there a better explanation? I just want to make sure that I have a correct understanding of why the output is as such.

jchanger
  • 739
  • 10
  • 29
wcj
  • 117
  • 1
  • 1
  • 7
  • 7
    you are using `c` and `d` uninitialized, which invokes undefined behaviour. Initialize them and you will see that their values do not change. – mch Feb 09 '16 at 08:51

4 Answers4

3

When a scanf conversion fails, the corresponding output variable, and all variables after that, are unchanged. So the example input, 0 A 0 sets b to 0, but doesn't change the values of c and d. Since c and d were not initialized, passing their values to printf results in undefined behavior. It was just a coincidence that c printed as 0.

A better test would be to initialize all of the variables to known values before calling scanf, e.g.

int main(void){

    int a = 101, b = 102, c = 103, d = 104;
    a = scanf("%d%d%d", &b, &c, &d);
    printf("Number of values read: %d\n", a);
    printf("Values read: %d %d %d\n", b, c, d);

    return 0;
}

Also, it's a good idea to use non-zero values for the test input (since 0 tends to be a common result for uninitialized variables), e.g. if the input is 5 A 7, then the output is

Number of values read: 1
Values read: 5 103 104

which clearly shows that a and b were changed, but c and d were not.

user3386109
  • 34,287
  • 7
  • 49
  • 68
1

Only 1 value was accurately given as input, so number of values read: 1

Correct!

2nd int is assigned value 0. The last int var is unassigned, so when printed, it returns garbage values.

Wrong - nothing would be read to c and d as your 2nd input (A) does not match with control string %d, thus the values of those are both un-itialized/garbage. You can prove that by printing c and d BEFORE and AFTER your scanf:

int a, b, c, d;   // 
printf("Initial values: %d %d\n", c, d);  // <-- c, d are garbage from here (1)
a = scanf("%d%d%d", &b, &c, &d);   // <-- scanf does not change `c` and `d` here because 2nd input is of wrong format 
printf("Number of values read: %d\n", a); 
printf("Values read: %d %d %d\n", b, c, d);   // <-- c, d remain garbage here (2). No guarantee but chances are the same as (1)

WARNING: the above code is to indicate your scanf in fact has no effect on c and d. In all case you should always initialize your variable before use.

int a = 1, b = 2, c = 3, d = 4;     // <-- always initialize before use (CORRECT CODE)
printf("Initial values: %d %d\n", c, d);    // <-- c = 3, d = 4
a = scanf("%d%d%d", &b, &c, &d);    // <-- scanf does not change `c` and `d` here because 2nd input is of wrong format 
printf("Number of values read: %d\n", a); 
printf("Values read: %d %d %d\n", b, c, d);    // <-- c = 3, d = 4
artm
  • 17,291
  • 6
  • 38
  • 54
  • 1
    reading from uninitialized variables is undefined behaviour, so it is possible that their values change between the first and third `printf`. – mch Feb 09 '16 at 09:04
  • Yeah. I mentioned that `c` and `d` are garbage. The `printf` is just a mean to show that his `scanf` does not have any effect. – artm Feb 09 '16 at 09:07
  • they are not only garbage, they can change because of the undefined behaviour. You should initialize them to some value. – mch Feb 09 '16 at 09:10
0

Outputting uninitialized variables causesundefined behaviour. This means anything may happen. There is not much reason to try and understand the exact output because it could change at the drop of a hat. The entire program behaviour is undefined, you cannot even rely on the first output or anything like that.

Any "explanation" you reason out by trial and error on your system may not work for another system, or another compiler, or if you change compiler settings, or even completely random fluctuations.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
0

Apart from the fact of the uninitialized variables, your are using scanf with the wrong scanf type specifiers, i.e. for the variable c you are providing as input a character and try to save it as a decimal integer. If you plan to read characters, you can define your varaibles as of type char and a better scanf line would be:

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

After that you can treat them as integers by printing them using the %d specifier, so you see their numeric representation, such as in:

printf("Values read: %d %d %d", b, c, d);

Or you can do a conversion char to int within your code if you prefer. More info about type specifiers for scanf is here.

Again, this is apart from the fact of you using unitialized variables, that other answers explained very well.

jchanger
  • 739
  • 10
  • 29