把一個字母'a'輸入一個int型變量導致的錯誤


題目:編寫一個程序,將用戶輸入的十進制短整型正數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博客


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM