先看一段代码:代码①
 #include <Windows.h> 
 
 int main() 
 
{ 
 
int n = 0; 
 
while (scanf( "%d", &n) != EOF)       //        如果输入a死循环 
 
{ 
 
printf( "b\n"); 
 
//getchar(); 
 
Sleep(1000); 
 
} 
 
return 0; 
 
} 
 
 
 
此程序的输出结果是        输出b       休眠1s        (自动读取a)        输出b        休眠1s 
 
反复循环。 
 
 
 
分析: 
 
输入a,但是%d读取的是10进制数字,所以认为读取的类型不符合, 
 
此时scanf并不会跳过a,而是把a重新放在缓冲区,下一次scanf读取的时候,还是会读取a! 
 
注意的是,并没有读取失败,只不过是在反复读取a。如果读取失败,那将无法进入循环! 
 
但注意的是,不同于以下程序:代码② 
 
 
int main()
 {
     int n = 'A';
     printf("%d", n);        
     return 0;
 }
这段程序不需要读取,只需要将A的ASC II码值,用10进制的形式打印出来!
  
再看代码③
 int main() 
 { 
 int n = 0; 
 int m = 0; 
 scanf( "%d %d", &n, &m);    //输入A 8 
 printf( "%d %d", n, m);       //打印 0 0         
 return 0; 
 } 
   输入A 8,此时scanf的第一个%d读取数据时,由于类型不符,所以A会停留在缓冲区,留给下一个%d读取,因此才会给  n  m赋值失败。(赋值失败不是读取失败,读取失败会返回EOF,接着往下读就明白了) 
     再看代码④ 
  int main() 
{
int n = 0;
int m = 0;
int ret = scanf("%d %d", &n, &m); //输入A 8
printf("%d",ret); //打印 0
return 0;
}
   {
int n = 0;
int m = 0;
int ret = scanf("%d %d", &n, &m); //输入A 8
printf("%d",ret); //打印 0
return 0;
}
分析:此时ret会scanf的返回值,但是由于给n m读取数值都没有读取进去,所以ret为0。 
    再看代码⑤ 
  int main() 
{
int n = 0;
int m = 0;
int ret = scanf("%d %d", &n, &m); //输入Ctrl + z 8
printf("%d",ret); //打印 -1
return 0;
}
   {
int n = 0;
int m = 0;
int ret = scanf("%d %d", &n, &m); //输入Ctrl + z 8
printf("%d",ret); //打印 -1
return 0;
}
分析:Ctrl + z会被认为成EOF,当scanf读取到EOF的时候,会认为读取失败,此时返回值为EOF(即-1) 
   再看代码⑥
int main()
 {
     int n = 0;
     int m = 0;
    int ret =  scanf("%d %d", &n, &m);    //输入8      Ctrl + z     
    printf("%d",ret);       //打印 1
    return 0;
 }
解析:
此时第一个%d成功读取到数字8,会读取成功,再读取到EOF,会被认为读取失败。
scanf的返回值是成功读取的元素个数,为 1
因为只有n是成功被读取的,m并没有被成功读入(m还是初始化的值)。
所以ret 为 1
总结:当死循环、莫名读取的时候,学会使用Sleep来检查缓冲区!!!
2.当读取的类型不符合时,不会跳过此元素
3.EOF会读取失败