这两天学到STL中的string容器,里面提到的字符串转化为数字的操作,用到了sscanf函数。我一看,发现这函数跟scanf很像,就想了解一下它的功能。于是乎我各种百度,看各种大神的博客,随了解到以下内容:
同:都是用于数据输入的函数。
异:scanf以屏幕(键盘)为输入源,sscanf以固定字符串为输入源。
先定义一个字符串str[10]="??????????"
,然后用sscanf函数对其操作,对比前后变化来感受sscanf函数的各种功能。
1、拷贝字符串
sscanf("abcde","%s",str);//
str="abcde\0????"
把源字符串拷贝到str的前5个字符,并把str的第六个字符赋值为空字符,即\0;
2、拷贝指定长度字符串
sscanf("abcde","%4s",str);//
str="abcd\0?????"
可以看到,只把源字符串的前4个字符拷贝到了str里面,并把str的第五个字符赋值为\0;
3、拷贝包含在指定字符集的字符
sscanf("abcABC","%[a-z]",str);//"%[a,z]"是不对的
str="abc\0??????"
只把包含在区间[a,z]的字符拷贝到str里面
4、拷贝不包含在指定字符集的字符
sscanf("abcABCabc","%[^A-Z]",str);
str="abc\0??????"
“ ^ ”表示逻辑非,所以,不属于A到Z的字符会被拷贝到str中去。但是为什么源字符串中明明有两个abc,却只拷贝进去一个呢?是因为当sscanf扫描到不符合条件(即属于A-Z)的字符时,就会结束扫描,跳出sscanf函数;
注:“^”后面可带多个条件,且都受其作用,如:[^a-zA]
表示^a-z且^A
(既不是小写字母,也不是大写A)。
5、sscanf中“ * ”的用法举例
sscanf("ABCaaaABC","%*[A-Z]%[^A-Z]",str);//
str="aaa\0??????"
“ * ”可理解为忽略,以上表示先忽略A-Z,然后拷贝不属于A-Z的字符给str。
注:“ * ”的用法可参考 : https://blog.csdn.net/dark_cy/article/details/83901978
6、利用“ %* ”拷贝两个指定字符之间的字符串
sscanf("ABChelloDEFGHIJK","%*[^C]C%[^D]",str);//分隔符为'C'
str="hello\0????"
拷贝字符'C'和'D'之间的字符串。要知道如果不用“*”过滤掉前面的字符,就没法拷贝中间的字符。
注:sscanf(“ABChelloDEFGHIJK”,"%*[ ^C]C%[ ^D]",str);红色部分的字符必须是一样的,表示把字符’C’忽略。
7、不用“ % * ”取中间字符串
刚说过这是不可能的
ssanf("AAAaaaBBB","%[a-z]",str);
如果你以为str="aaa\0??????",那你就错了,因为sscanf扫描到第一个字符'A'时就发现不符合[a-z],就会停止扫描了。
所以str并没有变,即str="??????????",这验证了(6)中所说不用“ * ”,无法拷贝中间的字符串。
特别说明:“%”不可连续使用(如%[a-z]%[A-Z]),连续使用会使后面的一个无意义。“%* ”可以连续使用(如%*[ a-z]% *[A-Z],表示先过滤小写字母,再过滤大写字母)。
8、利用sscanf把字符串转化成数字
int a,b,c;
char str1[100]="111,222,333";
//sscanf(str1,"%d,%d,%d",&a,&b,&c);效果一样,如果是string对象则不可这样
sscanf("111,222,333","%d,%d,%d",&a,&b,&c);
a=111;b=222,c=333;
同(6)一样,分隔符(百分号之间的符号。本列为“,”,也可以是其他各种符号)必须保持一致;
如:sscanf("1A2","%dA%d",&a,&b);//a=1;b=2;