Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scanf is overwriting a second variable

Tags:

c

scanf

I'm asking the user to type in two variables. First an unsigned integer a and second an unsigned character b. The reading in of a works fine, but after reading in b, a is 0.

I found out that the pointer to a is one greater than the pointer to b. I realized that when b is greater than 255 a is not 0 anymore. So it seem to me that scanf reads in more than one byte for b and overwrites a.

#include <stdio.h>

int main ()
{
    unsigned int a;
    unsigned char b;

    printf("a: ");
    scanf("%u", &a); /* 255 */
    printf("b: ");
    scanf("%hhu", &b); /* 17 */

    printf("a: %u\n", a); /* a: 0 */
    printf("b: %u\n", b); /* b: 17 */

    printf("pointer a: %u\n", &a); /* pointer a: 6422316 */
    printf("pointer b: %u\n", &b); /* pointer b: 6422315 */

    return 0;
}

Since I'm new to programming in C, I'm not sure what information is necessary to understand my problem. I'm using a 64 bit processor an this is the used compiler:

gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/8.2.0/lto-wrapper.exe
Target: mingw32
Configured with: ../src/gcc-8.2.0/configure --build=x86_64-pc-linux-gnu --host=mingw32 --target=mingw32 --prefix=/mingw --disable-win32-registry --with-arch=i586 --with-tune=generic --enable-languages=c,c++,objc,obj-c++,fortran,ada --with-pkgversion='MinGW.org GCC-8.2.0-3' --with-gmp=/mingw --with-mpfr=/mingw --with-mpc=/mingw --enable-static --enable-shared --enable-threads --with-dwarf2 --disable-sjlj-exceptions --enable-version-specific-runtime-libs --with-libiconv-prefix=/mingw --with-libintl-prefix=/mingw --enable-libstdcxx-debug --with-isl=/mingw --enable-libgomp --disable-libvtv --enable-nls --disable-build-format-warnings
Thread model: win32
gcc version 8.2.0 (MinGW.org GCC-8.2.0-3)
like image 550
Kaniee Avatar asked Jan 01 '23 23:01

Kaniee


1 Answers

The problem is in this line:

    scanf("%hhu", &b); /* 17 */

Microsoft's C runtime library does not implement %hhu (it was not part of the C standard prior to C99). This causes the input to be interpreted as a short (due to how MSVCRT interprets hh as h in the format specifier), and writes past the limits of b and overwrites parts of a.

To fix this problem, change the type of a to unsigned short and use %hu as the format specifier OR pass the -D__USE_MINGW_ANSI_STDIO flag to your compiler.

like image 140
S.S. Anne Avatar answered Jan 12 '23 22:01

S.S. Anne