題目:編寫一個程序,將用戶輸入的十進制短整型正數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,先留個網址以后再研究