程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> scnaf使用格式化字符串%d接受小數的情況

scnaf使用格式化字符串%d接受小數的情況

編輯:C++入門知識

在使用scanf的時候,因為需要傳遞整數,所以,很顯然格式化字符串使用“%d”,但是在測試的時候,有人就使用了小數,也就是誤輸入,那情況就糟糕了,舉一個簡單的例子:
[cpp] 
#include <stdio.h> 
int main() 

 int a,b,c; 
 //printf("a=%d,b=%d,c=%d\n",a,b,c); 
 while(1) 
 { 
   //fflush(stdin); 
   scanf("%d",&a); 
   scanf("%d",&b); 
   scanf("%d",&c); 
   printf("a=%d,b=%d,c=%d\n",a,b,c); 
   printf("---------------\n"); 
 } 
 return 0; 

如果輸入三個正確的正整數的話,那麼程序運行正常,例如輸入 1,2,3,那麼運行的結果就是
1 2 3
a=1,b=2,c=3
---------------
但是,如果不慎輸入小數的話,那麼整個程序就會崩潰的,因為顯示的太快了,於是我修改了一下程序,讓程序在下一個while循環的時候,休眠了兩秒鐘,如下:
[cpp] 
#include <stdio.h> 
#include <windows.h> 
int main() 

 int a,b,c; 
 //printf("a=%d,b=%d,c=%d\n",a,b,c); 
 while(1) 
 { 
     //fflush(stdin); 
   scanf("%d",&a); 
   scanf("%d",&b); 
   scanf("%d",&c); 
   printf("a=%d,b=%d,c=%d\n",a,b,c); 
   printf("---------------\n"); 
   Sleep(2000); 
 } 
 return 0; 

下面的假設我誤輸入了小數,看一下情況會怎麼樣:
2.3
a=2,b=-858993460,c=-858993460
---------------
a=2,b=-858993460,c=-858993460
---------------
a=2,b=-858993460,c=-858993460
---------------

程序一直死循環我們可以看到a的值是2,而b和c的值都是隨機值,然後通過通過在使用之前輸出a,b,c值,如下:
printf("a=%d,b=%d,c=%d\n",a,b,c);
輸出結果:
a=-858993460,b=-858993460,c=-858993460
可以看到每次循環的時候,它們的值都沒有發變化。想到了scanf的使用,我猜想一直死循環的原因就是scanf對輸入變量的記憶,如果把內存清空的話,是不是就不會發生類似的情況了呢?
於是,我在while循環的最開始添加了語句fflush(stdin);然後運行:
即使第一次輸入小數的時候,程序也不會崩潰。運行如下:
a=-858993460,b=-858993460,c=-858993460
4.2
a=4,b=-858993460,c=-858993460
---------------
1 2 3
a=1,b=2,c=3
---------------
.5
a=1,b=2,c=3
---------------
雖然沒有崩潰,但是,我們看到最後輸入“.5”的時候,a,b,c的值都沒有發生變化。
那如何在程序中識別這種情況呢?同桌給我了下面的一個程序:
[cpp] 
#include<stdio.h> 
int main() 

    int x,y; 
 printf("num3:%d\n",x); 
    while((y=scanf("%d",&x))==1) 
 { 
  printf("num1:%d\n",x); 
        printf("num2:%d\n",y); 
 } 
 printf("num3:%d\n",x); 
 printf("num3:%d\n",y); 
 return 0; 

下面是運行過程:
運行一:
x=-858993460
4
num1:4 --正常執行
num2:1 --scnaf的返回值表示成功讀入變量的個數,該程序返回1表示讀取正常
4.2
num1:4
num2:1 --當輸入小數的時候,第一次讀取的時候,讀取的是整數部分,通過返回的1可以看出來,變量賦值正確
num3:4 --但是,為什麼,它又退出程序了呢,而且第二次的返回值竟然是0,也就是賦值失敗,我只是輸入一個值
num4:0
Press any key to continue
運行2:
x=-858993460
.2
num3:-858993460 --當值輸入一個小數的時候,我們可以看到,其實變量x並沒有賦值,還是原來產生的那個隨機值
num4:0
Press any key to continue

通過上面的例子,我們可以看到,當我們通過scanf的時候,如果參數列表是“%d”,但是在運行的時候輸入的是小數的話,那麼第一次變量獲取的是小數點前面的部分,如果小數點前面有整數的話,那麼scanf就可以正常讀取輸入的值。但是,倘若我們接下來還有一個scanf的話,那麼該scanf就會去取輸入的小數去掉整數的部分,例如,當輸入“3.2”的時候,第一次讀取的是3,第二個scanf函數就不會讀取你輸入內容,而是會接受內存中沒有讀取的“.2”,這個時候,我們的變量就不會得到新的值,如果該變量(例如上面的x)原來賦值的話(獲取小數4.2的整數部分4),那麼它還是4,如果沒有賦值的話,它還是原來的隨機值,也就是,該變量中的值並沒有更新。其實避免影響第二次scanf的方法就是在執行第二個scanf的之前,清空內存,例如使用“fflush(stdin);”
如果把它放到了while循環的最後,例如去掉源程序中注釋的內容,重新編輯運行:
x=-858993460
2
num1:2 --整數正常
num2:1
5.6
num1:5 --小數獲取整數部分
num2:1 --正常
.2
num3:5 --變量的值並沒有重新寫入
num4:0 --讀取新值失敗,退出
Press any key to continue
從運行的結果可以看出,只要第一次輸入的內容不是以小數點開頭的話,那麼就可以繼續運行下去。
那麼在自己的程序中怎麼預防這樣的問題呢?
下面通過一個小例子來說明一下:
[cpp] 
#include <stdio.h> 
void main() 

 int num,ret; 
 while ((ret=scanf("%d",&num))!=1) 
 { 
  printf("輸入錯誤,請重新輸入:"); 
  fflush(stdin); 
  continue; 
 } 
 printf("你輸入的值是:%d,下面就可以使用了!\n",num); 

運行情況如下:
.2     --輸入的整數誤輸入多一個小數點
輸入錯誤,請重新輸入:2  --提示重新輸入
你輸入的值是:2,下面就可以使用了!
Press any key to continue

3.6    --輸入了小數
你輸入的值是:3,下面就可以使用了!--可以正確讀取其中的整數部分
Press any key to continue


如果擔心上面的誤操作會影響下面的scanf操作,那麼可以在使用該函數之前,使用“fflush(stdin);”清空一下內存。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved