使用fscanf读取含有数据间含有多个空格的数据

之前一直使用fortran处理数据

忽然发现C语言忘得差不多了

同时觉得fortran的编写规则太混乱 不利于程序开发的趋势

所以决定还是捡起C

采用C读取gulp的res文件计算径向分布函数

但是发现用fscanf(ip,"%d%lf%lf%lf"",&no,&x,&y,&z);读取类似这种数据时

   1       3.178903132     2.100312814     6.846356633

总是得不到正确的结果

后来发现网上说在格式控制后面加上*[^\n]%*c可行,一试果然可以

查询后发现完整的格式控制符应为[=%[*][width][modifiers]type=]

*号表示读取后忽略指定的数据不记录后面的变量(An optional starting asterisk indicates that the data is to be read from the stream but ignored, i.e. it is not stored in the corresponding argument.)

 

对于 const char* p = "12232114687ABC12356";
sscanf(p, "%[123]", buf); //
就把是'1''2''3'的字读读到buf中,直到遇到一个不是'1'且不是'2'且不是'3'的字符,于是执行后buf应该是"1223211";
%[123]
等同于%[231],等同于%[321]……,列表中的顺序是无所谓的;
%[123]
也等同于%[1-3]%[3-1],也就是“13”,对于连续的字符列表这样写就很简单,比如%[a-z]等同%[abc…省略…z]
想想看,%[3-14]应该等同于什么?是“314”吗?当然不是,因为[]中的是字符,而不是数字,所以%[3-14]应该等同于%[3214],等同于%[1234]
同理,想只取字母,那就可以写成%[A-Za-z]
如果列表的第一个字母是^,那么正好相反,比如%[^A-Za-z]的意思就是取字母之外的所有字符。
对于字符串"abDEc123"如果想按照字母和数字读到两个字符串中就应该是 "%[a-zA-Z]%[0-9]", buf1, buf2
假如我想取一行字符,该怎么办?"%s"是不行的,因为%s遇到空白字符(空格、制表符、\r\n)就结束了,所以可以写成"%[^\n]%*c"%[^\n]的作用刚才讲过了,就是读'\n'之外的所有字符,也就是说读到\n为止,'%*c'的作用就是把\n去掉,否则再次读的时候一直遇到的都是'\n'
所有对%s起作用的控制,都可以用于%[],比如"%*[^\n]%*c"就表示跳过一行,"%-20[^\n]"就表示读取\n20个字符。

 

我想fscanf在默认状态下应是读取到分隔符是自动停止 然后再按格式控制分配数据,

%[^\n]则强迫其读取‘\n’前的全部内容,再分配数据,因此就不会产生数据错乱的情况(待证实)

看来在编程中加入%[^\n]%*c是一个比较好的习惯

然而关于这一部分的内容

教材中却很少提及 实践出真知啊

参考

1.http://www.cnblogs.com/fangyu/archive/2011/03/29/1998605.html

2.http://www.cplusplus.com/reference/clibrary/cstdio/fscanf/

3.http://blog.chinaunix.net/space.php?uid=14121858&do=blog&id=216299

  • 8
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值