永发信息网

c++ 如何知道sscanf读取了多少个字符

答案:2  悬赏:0  手机版
解决时间 2021-03-09 09:56
比如 char str[] = "1.2+84.85";
sscanf(str, "%lf", &num);
我怎么知道读了3个char?
最佳答案
char str[10];

for (int i = 0; i < 10; i++) str[i] = '!';

执行完后str的值为

str = "!!!!!!!!!!"

我们把str的每个字符都初始化为惊叹号,当str的值发生变化时,使用printf打印str的值,对比先前的惊叹号,这样就可以方便的观察str发生了怎样的变化。下面我们做几个小实验,看看使用sscanf和正则表达式格式化输入后,str有什么变化。

实验1:

sscanf("123456","%s",str); ---------str的值为 "123456\0!!!"

这个实验很简单,把源字符串"123456"拷贝到str的前6个字符,并且把str的第7个字符设为null字符,也就是\0

实验2:

sscanf("123456","%3s",str); ---------str的值为 "123\0!!!!!!"

看到没有,正则表达式的百分号后面多了一个3,这告诉sscanf只拷贝3个字符给str,然后把第4个字符设为null字符。

实验3:

sscanf("aaaAAA","%[a-z]",str); ---------str的值为 "aaa\0!!!!!!"

从这个实验开始我们会使用正则表达式,括号里面的a-z就是一个正则表达式,它可以表示从a到z的任意字符,

在继续讨论之前,我们先来看看百分号表示什么意思,%表示选择,%后面的是条件,比如实验1的"%s",s是一个条件,表示任意字符,"%s"的意思是:只要输入的东西是一个字符,就把它拷贝给str。实验2的"%3s"又多了一个条件:只拷贝3个字符。实验3的“%[a-z]”的条件稍微严格一些,输入的东西不但是字符,还得是一个小写字母的字符,所以实验3只拷贝了小写字母"aaa"给str,别忘了加上null字符。

实验4:

sscanf("AAAaaaBBB","%[^a-z]",str); ---------str的值为 "AAA\0!!!!!!"

对于所有字符,只要不是小写字母,都满足"^a-z"正则表达式,符号^表示逻辑非。前3个字符都不是小写字符,所以将其拷贝给str,但最后3个字符也不是小写字母,为什么不拷贝给str呢?这是因为当碰到不满足条件的字符后,sscanf就会停止执行,不再扫描之后的字符。

实验5:

sscanf("AAAaaaBBB","%[A-Z]%[a-z]",str); ---------段错误

这个实验的本意是:先把大写字母拷贝给str,然后把小写字母拷贝给str,但很不幸,程序运行的时候会发生段错误,因为当sscanf扫描到字符a时,违反了条件"%[A-Z]",sscanf就停止执行,不再扫描之后的字符,所以第二个条件也就没有任何意义,这个实验说明:不能使用%号两次或两次以上

实验6:

sscanf("AAAaaaBBB","%*[A-Z]%[a-z]",str); ---------str的值为 "aaa\0!!!!!!"

这个实验出现了一个新的符号:%*,与%相反,%*表示过滤满足条件的字符,在这个实验中,%*[A-Z]过滤了所有大写字母,然后再使用%[a-z]把之后的小写字母拷贝给str。如果只有%*,没有%的话,sscanf不会拷贝任何字符到str,这时sscanf的作用仅仅是过滤字符串。

实验7:

sscanf("AAAaaaBBB","%[a-z]",str); ---------str的值为 "!!!!!!!!!!"

做完前面几个实验后,我们都知道sscanf拷贝完成后,还会在str的后面加上一个null字符,但如果没有一个字符满足条件,sscanf不会在str 的后面加null字符,str的值依然是10个惊叹号。这个实验也说明了,如果不使用%*过滤掉前面不需要的字符,你永远别想取得中间的字符。

实验8:

sscanf("AAAaaaBC=","%*[A-Z]%*[a-z]%[^a-z=]",str); ---------str的值为 "BC\0!!!!!!!"

这是一个综合实验,但这个实验的目的不是帮我们复习前面所学的知识,而是展示两个值得注意的地方:

注意1:%只能使用一次,但%*可以使用多次,比如在这个实验里面,先用%*[A-Z]过滤大写字母,然后用%*[a-z]过滤小写字母。

注意2:^后面可以带多个条件,且这些条件都受^的作用,比如^a-z=表示^a-z且^=(既不是小写字母,也不是等于号)。

实验9:

int k;

sscanf("AAA123BBB456", "%*[^0-9]%i", &k); ---------k的值为123

首先,%*[^0-9]过滤前面非数字的字符,然后用%i把数字字符转换成int型的整数,拷贝到变量k,注意参数必须使用k的地址。

[cpp] view plaincopy
#if 0
1,sscanf():从一个字符串中读进与指定格式相符的数据.
2,sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。
3,关于正则表达式:
(1)%[..],当字符属于方括号里表达式表示的字符集时继续读取,否则停止.方括号里的和正则表达式差不多,^是"排除..."的意思
(2)%*[..],直接跳过方括号里的字符集并继续读取
#endif

#include
using namespace std;

int main()
{
char str[10];
for (int i = 0; i < 10; i++) str[i] = '!';
cout< sscanf("123456","%s",str);//---------str的值为 "123456\0!!!"
//这个实验很简单,把源字符串"123456"拷贝到str的前6个字符,并且把str的第7个字符设为null字符,也就是\0
cout<
for (int i = 0; i < 10; i++) str[i] = '!';
sscanf("123456","%3s",str); //---------str的值为 "123\0!!!!!!"
//看到没有,正则表达式的百分号后面多了一个3,这告诉sscanf只拷贝3个字符给str,然后把第4个字符设为null字符。
cout<
for (int i = 0; i < 10; i++) str[i] = '!';
sscanf("aaaAAA","%[a-z]",str);// ---------str的值为 "aaa\0!!!!!!"
//从这个实验开始我们会使用正则表达式,括号里面的a-z就是一个正则表达式,它可以表示从a到z的任意字符,
//在继续讨论之前,我们先来看看百分号表示什么意思,%表示选择,%后面的是条件,比如实验1的"%s",s是一个条件,表示任意字符,"%s"的意思是:只要输入的东西是一个字符,就把它拷贝给str。实验2的"%3s"又多了一个条件:只拷贝3个字符。实验3的“%[a-z]”的条件稍微严格一些,输入的东西不但是字符,还得是一个小写字母的字符,所以实验3只拷贝了小写字母"aaa"给str,别忘了加上null字符。
cout<
for (int i = 0; i < 10; i++) str[i] = '!';
sscanf("AAAaaaBBB","%[^a-z]",str);// ---------str的值为 "AAA\0!!!!!!"
//对于所有字符,只要不是小写字母,都满足"^a-z"正则表达式,符号^表示逻辑非。前3个字符都不是小写字符,所以将其拷贝给str,但最后3个字符也不是小写字母,为什么不拷贝给str呢?这是因为当碰到不满足条件的字符后,sscanf就会停止执行,不再扫描之后的字符。
cout<


for (int i = 0; i < 10; i++) str[i] = '!';
sscanf("AAAaaaBBB","%*[A-Z]%[a-z]",str); //---------str的值为 "aaa\0!!!!!!"
//这个实验出现了一个新的符号:%*,与%相反,%*表示过滤满足条件的字符,在这个实验中,%*[A-Z]过滤了所有大写字母,然后再使用%[a-z]把之后的小写字母拷贝给str。如果只有%*,没有%的话,sscanf不会拷贝任何字符到str,这时sscanf的作用仅仅是过滤字符串。
cout<
for (int i = 0; i < 10; i++) str[i] = '!';
sscanf("AAAaaaBBB","%[a-z]",str);// ---------str的值为 "!!!!!!!!!!"
//做完前面几个实验后,我们都知道sscanf拷贝完成后,还会在str的后面加上一个null字符,但如果没有一个字符满足条件,sscanf不会在str 的后面加null字符,str的值依然是10个惊叹号。这个实验也说明了,如果不使用%*过滤掉前面不需要的字符,你永远别想取得中间的字符。
cout<
for (int i = 0; i < 10; i++) str[i] = '!';
sscanf("AAAaaaBC=","%*[A-Z]%*[a-z]%[^a-z=]",str); //---------str的值为 "BC\0!!!!!!!"
//这是一个综合实验,但这个实验的目的不是帮我们复习前面所学的知识,而是展示两个值得注意的地方:
//注意1:%只能使用一次,但%*可以使用多次,比如在这个实验里面,先用%*[A-Z]过滤大写字母,然后用%*[a-z]过滤小写字母。
// 注意2:^后面可以带多个条件,且这些条件都受^的作用,比如^a-z=表示^a-z且^=(既不是小写字母,也不是等于号)。
cout<
for (int i = 0; i < 10; i++) str[i] = '!';
int k;
sscanf("AAA123BBB456", "%*[A-Z]%i", &k); //---------k的值为123
//首先,%*[^0-9]过滤前面非数字的字符,然后用%i把数字字符转换成int型的整数,拷贝到变量k,注意参数必须使用k的地址。 cout< cout< return 0;
}
全部回答
字符串输入格式 , 逗号分隔 用 "%[^,], 格式。 逗号空白分隔 用 "%[^,' ']%*c: sscanf(str,"%[^,' ']%*c%lf,%lf,%lf",name,&ic1,&ic2,&ic3); 空白分隔 用 %s %lf %lf %lf 格式 #include using namespace std; #include #include int main() { char str[]="wang,3,4,5"; char name[10]; double ic1,ic2,ic3; sscanf(str,"%[^,],%lf,%lf,%lf",name,&ic1,&ic2,&ic3); printf("%s %lf %lf %lf\n",name,ic1,ic2,ic3); return 0; } 输出double型,可以用%lf 格式。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
奥比岛收满瓶,温柔美女表情。有一个的都来,最
白糖水加醋喝了有什么作用?
小车驾驶员安全带多少钱一条
昌德村这个地址在什么地方,我要处理点事
在我国基金募集申请监督的实践中,募集申请的
从普陀区到火车站有多远
缝纫机断线的原因
三极管极集电与发射极加电阻有什么作用
用凉开水,晒过的水,自来水养鱼哪个好?
什么是命题,特征是什么
gta5 win10 3dm破解版为什么总是停止工作?难
甲乙两车从相距800千米的两地相向而行,5小时
叶问茶人我想知道这个在什么地方
看到打斗场景就莫名地发抖是怎么回事?
高胜村地址有知道的么?有点事想过去
推荐资讯
用了精华和乳液之后还要再用霜吗
猫打疫苗前需要空腹吗
魔兽世界7.0前夕猎人怎么抓机械宠物
阅读材料,回答问题。(26分)材料一 世界某
医学伦理原则不含A.不伤害B.有利C.尊重D.胆识
铅笔+橡皮=橡皮头铅笔 还有什么和什么能组合
18岁有痘印适合用什么护肤品 日本的 (平价
脸上长痘痘,为什么他们说以后娶媳妇就没了,
不理她了,她坐立不安是什么意思
轩逸倒车影像不想用时能关闭吗?
在贷款审批中应该与授信品种相匹配的有()。A.
我发觉我变得不会笑了...而且笑起来样子很丑.
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?