题目:编写一个程序,将用户输入的十进制短整型正数n转换成二进制数。如果用户输入负数或者读入错误,则要求用户重新输入。 输入提示信息:"n=" **输入格式:"%hd" /* short 类型 */ 输出信息:"the binary number is " **输出格式要求:"%d" 程序运行示例如下: n=37 the binary number is 0000000000100101
一开始看到输出格式要求"%d"就想着只能输出一个数,提交了发现最大的二进制数会导致int爆掉,用lld输出不符合题意但是满足了一部分测试
1 #include <stdio.h> 2 #include <math.h> 3 #include <ctype.h> 4 int main(){ 5 short n; 6 int cnt = 0; 7 printf("n="); 8 scanf("%hd", &n); 9 while(n <= 0){ 10 printf("n="); 11 scanf("%hd", &n); 12 } 13 int v[17]; 14 long long binary = 0; 15 do{ 16 v[cnt + 1] = n % 2; 17 n /= 2; 18 cnt++; 19 }while(n); 20 for (int i = 0; i < cnt; i++){ 21 binary += v[i + 1] * pow(10, i); 22 } 23 printf("the binary number is %016lld", binary); 24 return 0; 25 }
提交后发现还是有一部分测试过不了,"如果用户输入负数或者读入错误,则要求用户重新输入。",也就是说如果输入的是字母要判断为输入错误并提示重新输入
一开始想到用<ctype.h>里的isalpha(n)来判断n输入的是不是字母,但是发现用%hd格式符根本不会读到字母a,a一直留在缓存区,scanf没有读到任何数值,n的数值就是定义时内存里随机的值,刚好是一个大于0的数,可以通过判断语句,所以无论输入a~z的任何字母,最后得到的二进制编码都是相同的
如果修改一下,把代码中的n先定义为通过不了if语句的n=0,那么在scanf读取失败后字母a一直留在缓存区,每次循环都会尝试从缓存区读取一个short型并且失败,程序就会一直循环输出"n="
然后去看了一下参考答案
1 #include <stdio.h> 2 #include <math.h> 3 void trans(short n, short b[]); 4 int main() 5 { 6 short b[16], n, i, read_in = 0; 7 for (i = 0; i <= 15; i++) 8 { 9 b[i] = 0; 10 } 11 do 12 { 13 printf("n="); 14 read_in = scanf("%hd", &n); 15 while(getchar()!=‘\n‘); //1 16 }while( n<0||read_in <1 ); //1 17 trans(n, b); 18 printf("the binary number is "); 19 for (i = 15; i >= 0; i--) 20 { 21 printf("%d", b[i]); //1 22 } 23 printf("\n"); 24 return 0; 25 } 26 void trans(short n, short b[]) //2 27 { 28 int i = 0; 29 while (n != 0) 30 { 31 b[i] = n % 2; //1 32 i++; 33 n /= 2; //1 34 } 35 36 }
大部分是大同小异,除了最后输出的部分是一个个输出而不是凑成一个很大的longlong型输出
最关键的是这段代码
1 do 2 { 3 printf("n="); 4 read_in = scanf("%hd", &n); 5 while(getchar()!=‘\n‘); //1 6 }while( n<0||read_in <1 ); //1
根据scanf的返回值:scanf 函数的返回值反映的是按照指定的格式符正确读入的数据的个数。 如果输入数据与指定格式不符,则会产生输入错误。 遇到输入错误,scanf函数会立即终止,返回已经成功读取的数据的个数。
用%hd去读取字母‘a‘会返回0,所以循环的条件就是判断读到n是数字大于0,read_in小于1时说明读到的不是数字,就要重新输入
while(getchar()!=‘\n‘);
这条语句是保证在读到非数字的字符后,把多余的字符全都从缓冲区移除,遇到下一个换行符时再进行下一次输入,很有效地解决了字母输入
在网上查了一下,大概类似与用cin输入一个字母到int很像,c++中可以用cin.clear()解除,但是学校oj平台只能用c,先留个网址以后再研究
解决对int型变量输入字符导致后续不能重新输入的情况_一个不像程序员的程序员的博客-CSDN博客
原文:https://www.cnblogs.com/mystsg/p/15332834.html