scanf()和sscanf()详解
文章目录
函数原型
int sscanf( string str, string fmt, mixed var1, mixed var2 ... );
int scanf( const char *format [,argument]... );
返回值
一般使用scanf函数时都是为某个变量赋值,不考虑它的返回值。但是任何函数都是需要返回的(即使返回类型用void,也可以认为只是调用了return语句,只是并没有返回什么东西而已),同样的scanf函数也是有返回的,它的返回值是成功读取变量的个数。如果有一个输入与变量格式不匹配,那么返回值为0。如:
scanf("%d %d", &num1, &num2);
如果输入两个中间有空格隔开的数字(如2 3),那么它的返回值是2。如果输入一个浮点数一个整数,则返回值是1。如果输入一个字符一个整数,则返回值是0。
在输入数据时,遇以下情况时认为该数据结束:
- 遇空格,或按“回车”或“跳格”(Tab)键;
- 按指定的宽度结束,如“%3d”,只取3列;
- 遇非法输入。
format格式解析
format可以是一个或多个
{%[\*] [width] [{h | l | I64 | L}]type | ' ' | '\t' | '\n' | 非%符号},
注:{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。
-
* 亦可用于格式中, (即 %*d 和 %*s) 加了星号 (*) 表示跳过此数据不读入. (也就是不把此数据读入参数中)
1 2 3 4 5const char sourceStr[] = "hello, world"; char buf[10] = {0}; sscanf(sourceStr, "%*s%s", buf); //%*s表示第一个匹配到的%s被过滤掉,即hello被过滤了 cout << buf<< endl; 结果为:world``
-
{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。
-
width表示读取宽度。
用法如下:
1 2 3 4 5const char sourceStr[] = "hello, world"; char buf[10] = {0}; sscanf(sourceStr, "%5s", buf); //%5s,只取5个字符 cout << buf<< endl; 结果为:hello``
-
{h | l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。
-
type :这就很多了,就是%s,%d之类。
格式匹配
scanf函数的<格式化字符串>与后面的<地址表>是必须严格匹配的。注意,是严格匹配,可以说不能有丝毫差别,但对于连续多个空格可以等同于一个空格。
格式匹配使用贪婪算法,即匹配尽可能多的匹配字符。
|
|
这是因为%s在匹配时直接把”kryptosx:001“全匹配掉了,应为贪心要求尽可能的匹配。4252772是x未初始化的值,因为x并没有匹配到输入。
type类型
%c 一个单一的字符
%d 一个十进制整数
%i 一个整数
%e, %f, %g 一个浮点数
%o 一个八进制数
%s 一个字符串
%x 一个十六进制数
%p 一个指针
%n 一个等于读取字符数量的整数
%u 一个无符号整数
%[] 一个字符集
%% 一个精度符
对于scanf函数的%c格式转换符,可以接受任何的非空白字符或空白字符(包括空格、回车、Tab甚至是F2这样的字符)。
集合操作
[ ]是个集合的标志,%[ ]特指读入此集合所限定的那些字符,比如%[A-Z]是输入大写字母,一旦遇到不在此集合的字符便停止。如果集合的第一个字符是“^”,这说明读取不在"^“后面集合的字符,既遇到”^“后面集合的字符便停止(这就是scanf函数里的正则表达式应用)。注意:此时读取的字符串是可以含有空格的。
%[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
%[aB’] 匹配a、B、‘中一员,贪婪性
%[^a] 匹配非a的任意字符,贪婪性
这和正则表达式很相似,而且仍然支持过滤,即可以有%*[a-z].如:
|
|
先将 “iios/“过滤掉,再将非’@‘的一串内容送到buf中,cool.得到结果。
怎样从sip:tom@172.18.1.133中取出tom?
|
|
示例
|
|
文章作者 Forz
上次更新 2017-07-23