Is there a way to use scanf to read an unsigned char decimal input into a uint8_t variable?
I am afraid if I read %hu or %u into a uint8_t, it may corrupt the adjacent memory because uint8_t is one byte, but %hu is 2 bytes, and %u is 4 bytes.
I am using MinGW32
gcc.exe (GCC) 4.9.3
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
The code I am worried about:
/* worried.c - issue demo code. */
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(int argc, char **argv)
{
uint8_t filler1 = 17; /* do not corrupt me please. */
uint8_t my_mem;
uint8_t filler2 = 39; /* do not corrupt me please. */
printf("please enter a number: $ ");
scanf("%u", &my_mem); /* corrupts fillers... */
// scanf("%hu", &my_mem); /* this also corrupts... */
// scanf("%hhu", &my_mem); /* still corrupts... */
// scanf("%"SCNu8, &my_mem); /* still corrupts... */
// scanf("%"PRIu8 "\n", &my_mem); /* still corrupts... */
printf("filler1 = %u.\n", filler1);
printf("my_mem = %u.\n", my_mem);
printf("filler2 = %u.\n", filler2);
return 0;
}
Note that the code above does corrupt the fillers, which is catastrophic when reading into a struct which is going to be directly written into a binary(record) file later.
I could solve it by casting from a temporary variable, but that takes a little extra work for my program which I was wondering if I could avoid forcing my program to do, and read into my_mem directly.
To date, it seems the solution that seems most likely is:
The only way to portably do this that works on GCC4.9.3 and newer is through casting. There are more elegant solutions on GCC5.2 e.g. %hhu, but they misbehave on GCC4.9.3.