問題:
說到scanf,爲了讓scanf從緩衝區讀取輸入流數據,最後都得一個回車。然而今天不小心發現一個有趣的現象。導致最後無論按幾個回車,輸入流數據都無法被scanf讀取。
程序入下:
#pragma warning(disable:4996)
#include <stdio.h>
#include<stdlib.h>
void main()
{
double x=0;
scanf("%lf\n",&x);
printf("輸出x:%lf\n",x);
fflush(stdin);
system("pause");
}
輸出入下,可以看出中間按了好多次回車,沒有用,直到隨便按了個4,再按回車纔有輸出。
分析:
原因在於scanf的讀取原理是匹配字符,但規則上是跳過 空格 回車 製表 空白字符的,從第一個非空白字符開始讀取。所以上述程序scanf會讀取一個數字,然後認爲接下來的第一個回車爲通知程序開始讀取緩衝區,%lf匹配了12.3,同時程序丟棄第一個回車,由於scanf的匹配串還差一個回車,所以scanf等待一個回車字符~~~問題就出在由於回車爲空白字符,所以scanf會跳過第一個之後4之前的所有回車,等待第一個出現的非空白字符和之後的回車,纔會再一次讀取緩衝區。是的這些回車符沒有起到通知程序開始讀取緩衝區的作用!!!
而在輸入4和之後的回車之後,程序以4之後的那個回車爲信號,開始再一次依次讀取緩衝區。此時緩衝區讀取順序從第二個輸入的回車開始。然後第二個回車和匹配到了scanf中的\n匹配成功,程序繼續執行,其他沒有匹配的字符依然停在緩衝區。
結論:
本文的問題主要是以下三點綜合作用導致的奇怪問題。充分理解此問題,對理解scanf讀取原理很有用。
1.scanf的匹配規則
2.回車的空白字符屬性
3.回車有通知scanf讀取緩衝區的獨特作用