在下面这个程序中,在main()函数里的scanf()收到从键盘输入的非零数之后却将该数变成零了,本人在几个编译器上都试过了,结果都一样。不知哪里出错了,敬请解惑,谢谢!
#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("%u", &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); // 此处显示b = 0,不知怎么回事呢。 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; }
解决方案
20
scanf(“%u”, &n);
%u对应的是unsigned int ,而不是unsigned short
%u对应的是unsigned int ,而不是unsigned short
10
假如要unsigned short,用 %hu
20
C语言中的格式占位符:
%a,%A 读入一个浮点值(仅C99有效)
%c 读入一个字符
%d 读入十进制整数
%i 读入十进制,八进制,十六进制整数
%o 读入八进制整数
%x,%X 读入十六进制整数
%s 读入一个字符串,遇空格、制表符或换行符结束。
%f,%F,%e,%E,%g,%G 用来输入实数,可以用小数形式或指数形式输入。
%p 读入一个指针
%u 读入一个无符号十进制整数
%n 至此已读入值的等价字符数
%[] 扫描字符集合
%% 读%符号
%a,%A 读入一个浮点值(仅C99有效)
%c 读入一个字符
%d 读入十进制整数
%i 读入十进制,八进制,十六进制整数
%o 读入八进制整数
%x,%X 读入十六进制整数
%s 读入一个字符串,遇空格、制表符或换行符结束。
%f,%F,%e,%E,%g,%G 用来输入实数,可以用小数形式或指数形式输入。
%p 读入一个指针
%u 读入一个无符号十进制整数
%n 至此已读入值的等价字符数
%[] 扫描字符集合
%% 读%符号
15
printf里面的%和变量的一一对应关系
scanf里面的%和变量以及变量前加不加&的一一对应关系
是C代码中非常容易出错的地方,而且通常编译还不出错。
所以在编译源代码之前值得专门仔细检查一遍甚至多遍。
在每个最后不带\n的printf后面加fflush(stdout);
在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin);
另外请检查scanf的返回值。
scanf里面的%和变量以及变量前加不加&的一一对应关系
是C代码中非常容易出错的地方,而且通常编译还不出错。
所以在编译源代码之前值得专门仔细检查一遍甚至多遍。
在每个最后不带\n的printf后面加fflush(stdout);
在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin);
另外请检查scanf的返回值。
//请今后要用 int c; scanf("%c",&c); //时,都改为 char s[2]; int c; scanf("%1s",s); c=s[0];