iwaswzq 阅读(870) 评论(3)
1、scanf输入数据的时候,它的参数表达式有过滤功能。比如:
int i,j,k;
scanf("%d空格%d空格%d空格",&i,&j,&k);
你输入 10空格20空格30回车, scanf开始处理,它把10 读入到i中,看到后面的空格,会自动删除之。虽然
最后30后面没有空格也没有关系。但是如果10后面或者20后面没有空格,或者是其它字符,比如:
10,20空格30回车,输入就会出错。当然多个空格也没有关系,例如:10空格空格20空格30回车。因为扫描
整数的时候会自动删除多余的空格。
如果用scanf("%d空格,%d,空格%d",&i,&j,&k); //注意空格和逗号的顺序,则输入和结果的比较是:
10空格,20,空格30               //和表达式正好匹配,没有问题
10,20,30                               //ok
10,空格20,空格30               //ok
10,空格20空格,30               //出错
10空格20空格30                 //更错
2、过滤具有多重功能。例如下面输入字符的例子:
 char c;
 for(;;)
 {
  scanf("%cabc",&c);
  if(c=='q')break;
  printf("c=%c\n",c);
 }
则在输入的字符串里面遇到a, ab, abc, 会自动删除。例如输入:
1a2ab3abc4bc5ba6aa7abca8
输出结果是:
c=1
c=2
c=3
c=4
c=b
c=c
c=5
c=b
c=6
c=a
c=7
c=a
c=8

可以看到实际的过滤情况,但是有意思的一点是scanf不会过滤bc,而且一旦成功过滤一组输入,
接下来的数据就会直接读入,例如遇到aa的情况,过滤掉a以后,下一个a被成功读入。

而且上面的例子,如果输入一些数据后,再输入q退出,则还会输出一个c=, 表明读入了一个回车符,
真的很奇怪。可以如下测试:
 char c;
 for(;;)
 {
  scanf("%cabc",&c);
  if(c=='q')break;
  if(c!='\n')
   printf("c=%c\n",c);
  else
   printf("haha!\n");
 }
3、再做进一步的测试,会发现更诡异的事情,把上面的代码改成:
  scanf("%c abc",&c); //注意abc前面的空格
你会发现输入q以后,程序并没有退出,还需要再输入一个字符。改成scanf("%c",&c);就没有问题了。

上述现象应该不是什么语法问题,是scanf这个函数本身的代码产生的问题。诸如下面这样的代码:
char a[20];
 scanf("%[A-Za-z ]s", a);
因为很少用到它,我不想再去研究了,谁感兴趣谁去弄吧,呵呵。

评论列表
freedk
re: scanf中有意思的过滤
呵呵。。
周星星
re: scanf中有意思的过滤
顶一下!
artifly
re: scanf中有意思的过滤
你说的这些奇怪的结果,如果用c语言的标准来分析的话都是完全正确的输出结果,也就是说既不是你的代码的问题,也不是scanf函数的实现代码的问题,而是c语言标准的问题,说得准确一点是标准中为scanf的控制字符串定义的糟糕匹配规则的问题

至于在输入q之后会输出回车也可以理解,那个回车其实是在输入q之前输入的就读入的,并放到输出缓存中的。输入q之后,程序退出,自动清空缓存,就会打印出回车。这个可以通过试验验证的。

发表评论
切换编辑模式