scanf 妙招

来源:互联网 发布:助创 众筹源码 编辑:程序博客网 时间:2024/05/16 01:00

scanf 妙招    
scanf原型:参见《C语言大全》和K&C
# include <stdio.h>;
int scanf( const char *format, ... );
函数 scanf() 是从标准输入流 stdin 中读内容的通用子程序,可以读入全部固有类型的数据并自动转换成机内形式。
在 C99 中,format 用 restrict 修饰。format 指向的控制串由以下三类字符组成:
       ● 格式说明符
       ● 空白符
       ● 非空白符
    
     转换字符(就是%后跟的部分)             
       a   读浮点值(仅适用于 C99)                                 
       A   读浮点值(仅适用于 C99)                                                 
       c   读单字符                                               
       d   读十进制整数                                           
       i   读十进制、八进制、十六进制整数                         
       e   读浮点数                                               
       E   读浮点数                                               
       f   读浮点数                                               
       F   读浮点数(仅适用于 C99)                                 
       g   读浮点数                                               
       G   读浮点数                                               
       o   读八进制数                                             
       s   读字符串                                               
       x   读十六进制数                                           
       X   读十六进制数                                           
       p   读指针值                                               
       n   至此已读入值的等价字符数                               
       u   读无符号十进制整数                                     
      [ ] 扫描字符集合                                           
       %   读 % 符号(百分号)  

妙招1, 读取以回车结尾的输入串:
scanf("%[^/n]",strings);
/*[]指定读取字符集,为 回车符号 的补集,这样就可以读取字符串,并允许在串中带入空格字符*/

妙招2, 及时吸收缓冲的回车字符:
scanf("%d%*c", &i);
/* “*” 格式控制符号,是读取一个指定格式数据,并丢弃该数据。
    在正常的输入情况下,比如输入整数时候, 终止输入时候会敲入一个回车,这个回车会滞留输入缓冲中,
    对于后续输入为整数没有影响,但是如果后续的scanf 读取字符或者是字符串(%s %c),那么,
    该滞留字符将被作为输入字符/字符串被接收*/


其中 [] 格式控制并不经常使用,但是不是说它的能力不足,
如果巧妙使用,可以有很多妙招, 这里就不一一列举了 .....

 

Trackback:http://hi.baidu.com/04se/blog/item/f84fee030cc73a8cd53f7c5d.html

 

 

下面内容来自:http://bbs.bccn.net/thread-260669-2-1.html

scanf里可以使用普通字符,它们用来要求你输入数据的格式:
相信你一定知道:scanf("%d, %d", &a, &b); 这种写法吧~
如果这么写你在输入的时候必须也输入一个数,然后逗号,再输入一个数,如果你输入一个数后,句号,再输入一个数。
那么a将会被正确赋值,而b就没有被赋值。这是因为读完那个整型之后,预计读入逗号的时候,匹配失败,因此scanf终止了些次读入!

我再举一个例子,可能见的就少一些了,但语法确实是样规定的:
比如你写:scanf("intput a number:%d", &a);
你再输入的时候必须打
intput a number:5
这样a才会正确的赋值。如果有任何差错,都会产生错误。

不过你在输入的时候可以任意允许插入空白字符的时候插入任意的空白字符:
比如你输入的是:input     a    number  :   5
甚至是:input
a
number

5
都可以正确执行。因为回车,tab,空格之类的都算空白字符。

现在在来看一下你说的那个问题:
你写的是:scanf("%f/n",&f)
2楼说scanf不解释转义字符,其实这是不对的。它应该还是会解释的。
只不过这个函数在读取完一个浮点数之后,会读一个回车。不过现在问题来了,你让它读一个空白字符,但允许插入空白字符的地方又可以插入任意多个空白字符,所以这个程序你可以不断地在那个浮点数之后插入回车,tab,空格之类的符号。所以这个程序会不停的往后读。这里只有一种合理的结束输入的方法,就是用ctrl-z来发出文件结束标记。终止scanf的读入。

当然你说在随便输入点什么也能结束,那是因为这个scanf指出那个空白字符之后应该什么也没有了,结果它又读到了非空白字符以外的字符,不是预期读入的东西,匹配失败,scanf终止了这次读入。不过这种终止没有带来什么错误而已,相对于%d,%d这种如果你输入的是1。(句号)2的话,那个2就会没读着,但如果你没能检测出这个错误,而以为2读着了,继续往后运行,就会发生不可预测的错误!

一种解决上述问题的方法是测试scanf的返回值。

scanf返回值是int。它用来表示它成功读取变量的个数。也有可能返回 0 或者 EOF 什么的。
   你可以用一个变量先接收它的返回值,比如:
    int num;
    num = scanf(……);
    if(num == 2) ……
  也可以,直接测:
    if(scanf() == 2) ……

 

来自:http://hi.baidu.com/hongszh/blog/item/62d54a82f7bc82aa0cf4d291.html

从scanf()的角度看输入

假定使用了 一个%d说明符来读取一个整数,scanf()函数开始每次读取一个输入字符,它跳过空白字符(空格,制表符和换行符)直到遇到一个非空白字符。因为它试 图读取一个整数,所以scanf()期望发现一个数字字符或者一个符号(+或者-)。如果它发现了一个数字或一个符号,那么它就保存之并读取下一个字符; 如果接下来的字符是一个数字,它保存这个数字,并读取下一个字符。就这样,scanf()持续读取和保存字符直到它遇到一个非数字的字符。

如果遇到了一个非数字的字符,它就得出结论,已读到了整数的尾部,scanf()把这个非数字字符放回输入,这就意味这当程序下一次开始读取输入时,它将从前面被放弃的那个非数字字符开始。最后,scanf()计算它所读取到的相应数值,并将该值放到指定的变量中。

如 果第一个非空白字符不是数字,将会发生什么呢?比如说,是A而非一个数字?这是scanf()会停在那里,并把A(或者不管是什么)放回输入,没有把任何 值赋值给指定变量,程序下一次读取输入时,它就从A处重新开始。如果程序中只有%d说明符,scanf()永远也不会超过那个A(去读下一个)。


如果使用%c说明符,那么所有的输入字符都是平等的,如果下一个输入字符是一个空格或者换行符,将会把这个空格或者换行符赋值给指定的变量。

如 果使用%s说明符,那么空白符以外的所有字符都是可以接受的,所以scanf()跳过所有空白符直到遇到第一个非空白符,然后保存再次遇到空白符之前的所 有非空白字符。这就意味着%s使scanf()读取一个单词,也就是说,一个不包括空白字符的字符串。当scanf()把字符串放到一个数组中时,它将添 加终止的'/0'使得数组成为一个C字符串。

原创粉丝点击