把一个字母'a'输入一个int型变量导致的错误

时间:2022-05-16 17:53:00   收藏:0   阅读:7
题目:编写一个程序,将用户输入的十进制短整型正数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

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!