我要用户输入两个变量。第一个是无符号整数a,第二个是无符号字符b。的读入a工作正常,但读入b后a为0。
我发现的指针a比的指针大1 b。我意识到,当b大于255时a不再为0。因此在我看来,要scanf读取b并覆盖多个字节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;
}
Run Code Online (Sandbox Code Playgroud)
由于我是C语言编程的新手,因此我不确定了解我的问题所需的信息是什么。我正在使用64位处理器,这是使用的编译器:
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)
Run Code Online (Sandbox Code Playgroud)
问题在这一行:
scanf("%hhu", &b); /* 17 */
Run Code Online (Sandbox Code Playgroud)
Microsoft的C运行时库未实现%hhu(它不是C99之前的C标准的一部分)。这导致输入被解释为short(由于MSVCRT 在格式说明符中的解释hh方式h),并超出的限制写入b并覆盖的部分a。
若要解决此问题,请将的类型更改a为unsigned short并%hu用作格式说明符,或将-D__USE_MINGW_ANSI_STDIO标志传递给编译器。
这几乎是关于在用MinGW编译的代码中打印size_twith 的值的各种问题的重复%zu。无论z和hh长度修改出现在C99。
C89描述了长度修饰符,如下所示
- 可选的
h,l(ELL)或L指示接收对象的大小。转换标识符d,i和n由前面h如果相应的参数是一个指向short int,而不是一个指针int,或者通过l,如果它是一个指向long int。类似地,转换说明o,u以及x应当由前面h如果相应的参数是一个指向unsigned short int,而不是一个指针unsigned int,或者通过l,如果它是一个指向unsigned long int。最后,如果相应的参数是指向的指针,而不是指向的指针,则转换说明符e,f和g必须在K之前。doublefloat,或者L如果它是longdouble 的指针。如果一个h,l或L与任何其他转换说明出现,则行为未定义。
该hh长度修改出现在C99。 C11 7.21.6.1p7说:
hh用于指定后续的
d,i,o,u,x,或X转换说明适用于签名char或unsigned char参数(该参数将已经根据整数促销促进,但它的值应被转换为符号的字符或印刷之前无符号字符); 或以下n转换说明符适用于指向带符号char参数的指针。
MinGW使用MSVCRT.DLL作为C库-该库仅支持C89。看到该%hhu行为时,根据C89尚未定义,但与将as解释为%hu并unsigned short在从起始的2个字节处写入值是一致的&a。
解决方法是将值读入临时unsigned short或中unsigned int,然后将其分配给unsigned char。