【发布时间】:2016-03-24 00:29:16
【问题描述】:
有没有办法使用 scanf 将 unsigned char 十进制输入读入 uint8_t 变量?
我担心如果我将 %hu 或 %u 读入一个 uint8_t,它可能会损坏相邻的内存,因为 uint8_t 是 1 个字节,但 %hu 是 2 个字节,而 %u 是 4 个字节。
我正在使用 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.
我担心的代码:
/* 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;
}
请注意,上面的代码确实损坏了填充器,当读取到稍后将直接写入二进制(记录)文件的结构时,这是灾难性的。
我可以通过从临时变量进行强制转换来解决它,但这需要我的程序做一些额外的工作,我想知道是否可以避免强制我的程序这样做,并直接读入 my_mem。
迄今为止,似乎最有可能的解决方案是:
在 GCC4.9.3 和更高版本上进行此操作的唯一方法是 通过铸造。 GCC5.2 上有更优雅的解决方案,例如%h, 但他们在 GCC4.9.3 上行为不端。
【问题讨论】:
-
scanf("%" SCNu8, &my_mem);(使用#include <inttypes.h>) -
我试过了,好像不能编译。导入header后也不知道SCNu8是什么。
-
@BLUEPIXY 是对的。但是,如果您只关心
scanf()的类型小于short,则可以使用%hhu到scanf()和unsigned char。 -
scanf("%hhu", &my_mem);将两个填充符都变为 0 :\
-
无法复制。
"%hhu"和"%"SCNu8都可以正常工作。
标签: c