# include <stdio.h>
void main()
{
     int n;
     scanf(“%dn”,&n);
     printf(“you typed %dn”,n);
}

scanf的某些特性,scanf特性

   以上的代码要怎么样输入?

scanf是很敏感的,最好不要在scanf下做精度、场宽的设置,否则输入可能会失效。

例:

#include <stdio.h>

int main(void)
{
  int a = 0;
  scanf(“%5d”,&a);
  printf(“a = %d”,a);
return 0;
}

我运行这个代码,在输入整数小于等于5位的时候没问题,输出正确。当输入整数多于5位的时候,它只会读取到第五位,而不读取剩下的输入。那么那些多于五位的输入是丢弃了吗?不是的,这又是scanf的一个特性。当scanf()未能读取指定形式的输入时,它就留下这个不相容的输入,以供下次进行读取。

修改上述代码

#include <stdio.h>

int main(void)
{
  int a = 0;
  int b = 0;
  scanf(“%5d”,&a);
澳门新葡萄京所有网站,   printf(“a = %dn”,a);
  scanf(“%d”,&b);
  printf(“b = %dn”,b);
return 0;
}

运行结果如下

澳门新葡萄京所有网站 1

 

这个特性如果不加注意,可能在后续编程中遇到某些问题调试不出来,所以还是有必要理解一下的。

 

再看一个例子

#include <stdio.h>

int main(void)

{

  int a;

  int status = 0;

  printf(“Enter an integer:(q to quit)”);

  status = scanf(“%d”,&a);

  while(status = 1)

  {

     printf(“Enter next integer:(q to quit)”);

     status = scanf(“%d”,&a);

  }

  printf(“Finished”);

return 0;

}

 

这个例子本意是为了告诫大家,不要在应该使用==的地方使用=。

但也可以说明scanf的上述特性。运行该程序会发现,不输入q时程序运行正常,在输入q后,程序开始无限循环,用户没有机会进行更多的输入。WHY?

这是因为,输入q,status被设置为0,但是在循环判断时又把status重置为1并开始另一次循环。BESIDES,scanf想读取的使%d类型,即整型,而q不是整型,所以q不被读取,留在缓冲区等待下一个scanf读取。而当到下次循环时,读取前面留下来的q,scanf再次失败,这就是为什么用户无法再输入的原因。

 

原因:

 scanf下一个特性

scanf(“%d”,&a);该语句要读入一个整数,并将其赋给a。

当读入的不是整数时,有下列情况

1.
输入的是空白字符(制表符,空格,换行符),scanf会跳过空白字符直到第一个非空白字符处,然后它会一直读取字符,直到遇到空白字符,或遇到一个不符合正在读取的类型的字符。所以scanf(“%d%d”,&a,&b);
  scanf(“%d       %d”,&a,&b);  scanf(“%d                  
 %d”,&a,&b);的行为是相同的

 

2.
输入的是不符合正在读取类型的字符,比如字母,它会保留这个不相容的字符,留待下一个scanf读入。

浮点数也类似。

 

但是对于%c来说,情况略微有所不同。

因为对于%c说明符,所有的输入字符都是平等的。如果下一个输入字符是一个空格或者换行符(不论是本次输入的还是之前遗留下来的),将会把这个空格或换行符赋给指定的变量;不会跳过空白字符。

但是!向格式字符串中添加一个空格将会导致一些区别。

命令scanf(“%c”,&ch);读取在输入中遇到的第一个字符,而scanf(”
%c”,&ch);则读取遇到的第一个非空白字符。

注意空格的位置是在%c整体之前,而非% c

 

这为我们提供了一种吃掉缓冲区换行符的思路。以往如果在scanf(“%c”,&ch);之前又scanf,我们不得不用fflush(stdin);或者添加一个%*c来吃掉换行符。但是现在,我们有了新方法,而且更加简便易行。那就是在以scanf(”
%c”,&ch);取代scanf(“%c”,&ch);

 

格式字符串中的空格意味着跳过下一个输入项之前的任何空格,注意,任何空格的概念也包括没有空格的特殊情况。

scanf(“%d,    %d”,&a,&b);将会接受下列任何一行输入

88,21

88,       21

88,           21  注意逗号是英文标点,且逗号要紧跟第一个数字

scanf(“%d   ,    %d”,&a,&b);将会接受下列任何一行输入

88,21

88  ,    21

88,           21

88                    ,

21

 

———————————————————————————————————————————————————————————————————————————

scanf是很敏感的,最好不要在scanf下做精度、场宽的设置,否则输入可能会失效。
例: #include stdio.h int main(void)…

n在scanf格式串中不表示等待换行符,而是读取并放弃连续的空白字符。(事实上,scanf格式串中的任何空白字符都表示读取并放弃空白字符。而且,诸如%d这样的格式也会丢掉前边的空白,因此你通常根本不需要在scanf格式串中加入显式的空白。)
   
因此,“%dn”中的n会让scanf读取到非空白字符串为止,而它可能需要读到下一行才能找到这个非空白字符串。这种情况下,去掉n仅仅使用“%d”即可(但你的程序可能需要跳过那个没有读入的换行符。)
参考:《你必须找到的495个C语言问题》
——Steve Summit著
——孙云,朱群英 译
——人民邮政出版社

思考下面问题:

# include <stdio.h>
void main()
{
     int n,m;
     scanf(“%d-%dn”,&n,&m);
     printf(“you typed %dn”,n);
     printf(“you typed %dn”,m);
}

怎么输入?输出什么,是不是和自己预想的一样?