提问人:Michael May 提问时间:8/27/2016 更新时间:8/27/2016 访问量:235
scanf() 可以将非零输入转换为零吗
Can scanf() turn non-zero input into zero
问:
在下面的代码中,main() 中的 scanf() 将其中一个输入数字从非零数字转换为零,如 while 循环中的调试 printf() 所示。我已经在几个编译器上测试了它,但只是为了继续得到相同的结果。请告诉我为什么会这样,请帮助我。谢谢。
#include <stdio.h>
unsigned srl (unsigned x, int k)
{
/* perform shift arithmetically */
printf("x = %u, (int) x= %d\n", x, (int) x);
unsigned xsra = (int) x >> k;
printf("\nxsra before was: %u\n", xsra);
unsigned test = 0xffffffff;
test <<= ((sizeof (int) << 3) - k); // get e.g., 0xfff00...
printf("test after shift is: %x, xsra & test = %x\n", test, xsra & test);
if (xsra & test == 0) // if xsrl is positve
return xsra;
else
xsra ^= test; // turn 1s into 0s
return xsra;
}
int sra (int x, int k)
{
/* perform shift logically */
int xsrl = (unsigned) x >> k;
unsigned test = 0xffffffff;
test << ((sizeof (int) << 3) - k + 1); // get e.g., 0xffff00...
if (xsrl & test == 0) // if xsrl is positve
return xsrl;
else
xsrl |= test;
return xsrl;
}
int main(void)
{
int a;
unsigned b;
unsigned short n;
puts("Enter an integer and a positive integer (q or negative second number to quit): ");
while(scanf("%d%u", &a, &b) == 2 && b > 0)
{
printf("Enter the number of shifts (between 0 and %d): ", (sizeof (int) << 3) - 1);
scanf("%d", &n);
if (n < 0 || n >= ((sizeof (int)) << 3))
{
printf("The number of shifts should be between 0 and %d.\n", ((sizeof (int)) << 3) - 1);
break;
}
printf("\nBefore shifting, int a = %d, unsigned b = %u\n", a, b);
a = sra(a, n);
b = srl(b, n);
printf("\nAfter shifting, int a = %d, unsigned b = %u\n", a, b);
puts("\nEnter an integer and a positive integer (q or negative second number to quit): ");
}
puts("Done!");
return 0;
}
答:
4赞
lnyng
8/27/2016
#1
问题是,它的大小小于正常的 。调用 时,它会将值读入,如果内存位置紧跟在 后面,则可能会覆盖现有值。n
unsigned short
int
scanf("%d", &n);
n
b
b
n
您所要做的就是将有问题的行更改为:
scanf("%hu", &n);
是从这里开始的 的修饰符。h
unsigned short int
评论
2赞
RastaJedi
8/27/2016
这是另一个示例,说明为什么您应该始终使用 和 进行编译。-Wall
-Wextra
0赞
Michael May
8/28/2016
谢谢你,梁。你的回答很有帮助。没错,由于输入格式说明符不正确,因此会出现溢出。
0赞
Michael May
8/28/2016
再次感谢你,RastaJedi。我假设 -Wall 和 -Wextra 选项是默认值,但实际上并不是每个编译器的默认值
评论
unsgined short
%hu
%u
n
n
unsigned
%d
%u
n