呼叫scanf函式的一個陷阱

我們在寫C程式時,經常使用scanf函式,讓使用者輸入資料,可是有時候會出現一些很奇怪的問題。例如,下面的程式是一個簡單的四則運算:

#include <stdio.h>
int main()
{
char ope = '\0';//操作符  - * /
int para1 = 0, para2 = 0, result = 0;//para1是運算引數1,para2是運算引數2,result是運算結果
printf("請輸入第一個運算引數\n");
scanf("%d",¶1);
printf("請輸入運算子 '  - * /'\n");
scanf("%c",&ope);
printf("請輸入第二個運算引數\n");
scanf("%d",¶2);
switch(ope)
{
case ' ': result = para1   para2;//如果運算子是 ,就執行加法運算
break;
case '-': result = para1 - para2;//如果運算子是-,就執行減法運算
break;
case '*': result = para1 * para2;//如果運算子是*,就執行乘法運算
break;
case '/': result = para1 / para2;//如果運算子是/,就執行除法運算
break;
default: printf("運算子輸入錯誤\n");//
break;
}
printf("運算結果是: %d\n", result);
return 0;    
}

此程式不管從語法,還是邏輯上,都沒有問題,且編譯也能通過。實際執行時,卻是如下結果:

在使用者輸入第一個運算引數後,按照程式的設定,應該讓使用者輸入運算子,可是直接讓使用者輸入第二個運算引數了。你能看出這是為什麼嗎? 
我們修改下程式,如下:

#include <stdio.h>
int main()
{
char ope = '\0';//操作符  - * /
int para1 = 0, para2 = 0, result = 0;//para1是運算引數1,para2是運算引數2,result是運算結果
printf("請輸入第一個運算引數\n");
scanf("%d",¶1);
printf("請輸入運算子 '  - * /'\n");
scanf("%c",&ope);
printf("運算子是: %d\n", ope);
printf("請輸入第二個運算引數\n");
scanf("%d",¶2);//加入這兩行程式碼
switch(ope)
{
case ' ': result = para1   para2;//如果運算子是 ,就執行加法運算
break;
case '-': result = para1 - para2;//如果運算子是-,就執行減法運算
break;
case '*': result = para1 * para2;//如果運算子是*,就執行乘法運算
break;
case '/': result = para1 / para2;//如果運算子是/,就執行除法運算
break;
default: printf("運算子輸入錯誤\n");//
break;
}
printf("運算結果是: %d\n", result);
return 0;    
}

我們加入兩行程式碼,輸出字元引數ope的ASCII碼值,結果如下:

可以看到,ope的ASCII碼值是10,正是換行符的ASCII碼值。我們什麼時候把換行符給了ope?
其實,在我們給運算引數para1賦值1的時候,我們按下了回車鍵,準備輸入運算子,可是系統不懂啊,系統把回車鍵理解為換行符賦值給了ope,所以接下來會跳過讓使用者輸入運算子而直接讓使用者輸入運算引數2了,問題就在這裡。

知道了問題所在,那麼就好解決了。
請看:

#include <stdio.h>
#include <conio.h>
int main()
{
char ope = '\0';//操作符  - * /
int para1 = 0, para2 = 0, result = 0;//para1是運算引數1,para2是運算引數2,result是運算結果
printf("請輸入第一個運算引數\n");
scanf("%d",¶1);
getchar();
printf("請輸入運算子 '  - * /'\n");
scanf("%c",&ope);
getchar();
printf("運算子是: %d\n", ope);
printf("請輸入第二個運算引數\n");
scanf("%d",¶2);
switch(ope)
{
case ' ': result = para1   para2;//如果運算子是 ,就執行加法運算
break;
case '-': result = para1 - para2;//如果運算子是-,就執行減法運算
break;
case '*': result = para1 * para2;//如果運算子是*,就執行乘法運算
break;
case '/': result = para1 / para2;//如果運算子是/,就執行除法運算
break;
default: printf("運算子輸入錯誤\n");//
break;
}
printf("運算結果是: %d\n", result);
return 0;    
}

在每次scanf結束後,加入getchar函式,即可。getchar函式從輸入流中讀取一個字元,因此可以接收我們每次按下的回車鍵,也就是換行符。執行結果如下: