Home > database >  why scanf can change other variable which is not argument?
why scanf can change other variable which is not argument?

Time:07-14

Here is code

#include <stdio.h>
int main(){
    unsigned char mem[32];

    int i,j;
    for(i=0;i<32;i  ){
        unsigned char a[8];
        scanf("%s",a);
        for(j = 0;j<8;j  ){
            mem[i] <<=1;
            mem[i] |= a[j] == '0' ? 0 : 1;
        }
    }
...
}

Input is a number in binary representation. I want to read them and store them into unsigned char array. When i equals 0, mem[0] = 0x3E. But when i equals 1, mem[0] will change to 0x0 as soon as scanf execute. And other inputs is fine. I have no idea about it. Input as follow

00111110
10100000
01010000
11100000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00111111
10000000
00000010
11000010
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
11111111
10001001

CodePudding user response:

You are invoking undefined behavior by having scanf() write out-of-bounds of the array a.

8-character strings like 00111110 will occupy 9 bytes of the memory including the terminating null-character, so you have to allocate enough buffer.

Also you should limit the number of characters to read to prevent buffer overrun.

Another point is that you should check if scanf() succeeded to read what is expected.

There also is another undefined behavior: you used values of mem[i], which is uninitialized non-static local variable. Such values are indeterminate and mustn't be used in calculations.

In conclusion, the part

unsigned char a[8];
scanf("%s",a);

should be

char a[9];
if (scanf("%8s",a) != 1) {
    fputs("read error\n", stderr);
    return 1;
}
mem[i] = 0;

Also note that I used char instead of unsigned char because %s format specifier expects char* and there aren't seem any code that should require unsigned char instead of char.

CodePudding user response:

a is too short it has to be char a[9] to accommodate null terminating character. Also use scanf("%8s",a);

  •  Tags:  
  • c
  • Related