function
<cstdio>
sscanf
int sscanf ( const char * s, const char * format, ...);
Read formatted data from string
Reads data from s and stores them according to parameter format into the locations given by the additional arguments, as if scanf was used, but reading from s instead of the standard input (stdin). The additional arguments should point to already allocated objects of the type specified by their corresponding format specifier within the format string. Parameters
s
C string that the function processes as its source to retrieve the data.
format
C string that contains a format string that follows the same specifications as format in scanf (see scanf for details).
... (additional arguments)
Depending on the format string, the function may expect a sequence of additional arguments, each containing a pointer to allocated storage where the interpretation of the extracted characters is stored with the appropriate type.
There should be at least as many of these arguments as the number of values stored by the format specifiers. Additional arguments are ignored by the function. Return Value
On success, the function returns the number of items in the argument list successfully filled. This count can match the expected number of items or be less (even zero) in the case of a matching failure.
In the case of an input failure before any data could be successfully interpreted, EOF is returned.
函数原型:
int sscanf( const char *, const char *, ...);
int sscanf(const char *buffer,const char *format,[argument ]...);
buffer存储的数据
format格式控制字符串
argument 选择性设定字符串
sscanf会从buffer里读进数据,依照format的格式将数据写入到argument里。

头文件

#include<stdio.h> 或者
#include <cstdio>

返回值

成功则返回参数数目,失败则返回-1,错误原因存于errno中。
经多次测试[来源请求],在linux系统中成功返回的是成功转换的值的个数,例如:
sscanf("1 2 3","%d %d %d",buf1, buf2, buf3); 成功调用返回值为3,即buf1,buf2,buf3均成功转换。
sscanf("1 2","%d %d %d",buf1, buf2, buf3); 成功调用返回值为2,即只有buf1,buf2成功转换。
(注意:此处buf均为地址)

sscanf与scanf类似,都是用于输入的,只是后者以键盘(stdin)为输入源,前者以固定字符串为输入源。

格式控制符,类似于正则表达式:

sscanf的第二个参数可以是一个或多个 {%[*] [width] [{h | I | I64 | L}]type | ' ' | '\t' | '\n' | 非%符号}
注:
1、 * 亦可用于格式中, (即 %*d 和 %*s) 加了星号 (*) 表示跳过此数据不读入. (也就是不把此数据读入参数中)
2、{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。
3、width表示读取宽度。
4、{h | l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。
5、type :这就很多了,就是%s,%d之类。
6、特别的:%*[width] [{h | l | I64 | L}]type 表示满足该条件的被过滤掉,不会向目标参数中写入值
失败返回0 ,否则返回格式化的参数个数

支持集合操作

%[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
%[aB'] 匹配a、B、'中一员,贪婪性
%[^a] 匹配非a的任意字符,并且停止读入,贪婪性

例子

1. 常见用法。
1
2
3
char buf[512];
sscanf("123456","%s",buf);//此处buf是数组名,它的意思是将123456以%s的形式存入buf中!
printf("%s\n",buf);
结果为:123456
2. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
1
2
sscanf("123456","%4s",buf);
printf("%s\n",buf);
结果为:1234
3. 取到指定字符为止的字符串。如在下例中,取遇到任意小写字母为止的字符串。
1
2
sscanf("123456abcdedf","%[^a-z]",buf);
printf("%s\n",buf);
结果为:123456
4. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。
1
2
sscanf("123456abcdedfBCDEF","%[1-9a-z]",buf);
printf("%s\n",buf);
结果为:123456abcdedf
当输入:  sscanf("123456abcdedfBCDEF","%[1-9A-Z]",buf);
1
printf("%s\n",buf);
结果为:123456BCDEF(错!!)
注:结果应该为:123456【因为遇到不是1-9或者A-Z的字符时,即遇到小写字母时,就已经结束】
5. 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。
1
2
sscanf("123456abcdedfBCDEF","%[^A-Z]",buf);
printf("%s\n",buf);
结果为:123456abcdedf
6、给定一个字符串iios/12DDWDFF@122,获取 / 和 @ 之间的字符串,
先将 "iios/"过滤掉,再将非'@'的一串内容送到buf中
1
2
sscanf("iios/12DDWDFF@122","%*[^/]/%[^@]",buf);
printf("%s\n",buf);
结果为:12DDWDFF
7、给定一个字符串“hello, world”,仅保留world。
(注意:“,”之后有一空格,%s遇空格停止,加*则是忽略第一个读到的字符串)
1
2
sscanf(“hello, world”,"%*s%s",buf);
printf("%s\n",buf);
结果为:world
%*s表示第一个匹配到的%s被过滤掉,即“hello,”被过滤了
如果没有空格则结果为NULL。
8、最简明的格式是tab间隔的字符串
1
2
sscanf(“字符串1\t字符串2\t字符串3”,"%s%s%s",str1,str2,str3);
printf("%s\t%s\t%s\n",str1,str2,str3);
结果为:字符串1 字符串2 字符串3
 

sscanf及sscanf_s的常用方法,原来安全版本的函数,对参数和缓冲边界做了检查,增加了返回值和抛出异常。这样增加了函数的安全性,减少了出错的几率。
同时这也意味着在使用这些函数时,有时你不得不输入更多的关于缓冲区大小的参数,多敲几下键盘能换来更少的麻烦,值得!

下面总结了sscanf的以及sscanf_s的常用方法,也体现了“_s”版本函数与原函数的特别之处:

1、sscanf和scanf的不同是输入来源,前者是一个字符串,后者则是标准输入设备

2、sscanf的使用,以解析时间字符串为例,将字符串“2009-01-02_11:12:13”解析为整型年月日时分秒

//定义
 char cc;
 tm tm_temp={0};
 string stime("2009-01-02_11:12:13");

(1) 必须严格按照分隔符形式匹配填写,若遇到不匹配项则终止解析

sscanf(stime.c_str(), "%4d-%2d-%2d_%2d:%2d:%2d",
  &tm_temp.tm_year, 
  &tm_temp.tm_mon, 
  &tm_temp.tm_mday, 
  &tm_temp.tm_hour, 
  &tm_temp.tm_min, 
  &tm_temp.tm_sec
  );
(2) 可以不按照分割符号形式填写,字符数必须一致,例如可以正确解析“2009/01/02_11:12:13”

sscanf(stime.c_str(), "%4d%c%2d%c%2d%c%2d%c%2d%c%2d",
  &tm_temp.tm_year, &cc,
  &tm_temp.tm_mon, &cc,
  &tm_temp.tm_mday, &cc,
  &tm_temp.tm_hour, &cc,
  &tm_temp.tm_min, &cc,
  &tm_temp.tm_sec
  );
 
(3) 可以不按照分割符号形式填写,字符数必须一致,同上,%1s可以等同于%c

sscanf(stime.c_str(), "%4d%1s%2d%1s%2d%1s%2d%1s%2d%1s%2d",
  &tm_temp.tm_year, &cc,
  &tm_temp.tm_mon, &cc,
  &tm_temp.tm_mday, &cc,
  &tm_temp.tm_hour, &cc,
  &tm_temp.tm_min, &cc,
  &tm_temp.tm_sec
  );

(4) 可以不按照分割符形式和数量填写,类型必须一致,例如可以正确解析“2009/01/02___11:12:13”
这里使用了sscanf的正则表达式,与通用的正则表示类似但不完全相同,%*c表示忽略连续多个字符

sscanf(stime.c_str(), "%4d%*c%2d%*c%2d%*c%2d%*c%2d%*c%2d",
  &tm_temp.tm_year, 
  &tm_temp.tm_mon, 
  &tm_temp.tm_mday, 
  &tm_temp.tm_hour, 
  &tm_temp.tm_min, 
  &tm_temp.tm_sec
  );
  
3、sscanf_s的使用

//定义
 char cc[2];
 tm tm_temp={0};
 string stime("2009-01-02_11:12:13");

(1) 与sscanf第一种方法相同,可以使用"%4d-%2d-%2d_%2d:%2d:%2d"格式匹配解析

sscanf_s(stime.c_str(), "%4d-%2d-%2d_%2d:%2d:%2d",
   &tm_temp.tm_year, 
   &tm_temp.tm_mon, 
   &tm_temp.tm_mday, 
   &tm_temp.tm_hour, 
   &tm_temp.tm_min, 
   &tm_temp.tm_sec
   );
(2) 使用%c格式对数据解析时,必须对相应的缓冲区增加长度参数,否则将会出错

sscanf_s(stime.c_str(), "%4d%c%2d%c%2d%c%2d%c%2d%c%2d",
  &tm_temp.tm_year, &cc, 1,
  &tm_temp.tm_mon, &cc, 1,
  &tm_temp.tm_mday, &cc, 1,
  &tm_temp.tm_hour, &cc, 1,
  &tm_temp.tm_min, &cc, 1,
  &tm_temp.tm_sec
  );
(3) 使用%s格式对数据解析时,缓冲长度必须大于字符串长度,否则不予解析

sscanf_s(stime.c_str(), "%4d%1s%2d%1s%2d%1s%2d%1s%2d%1s%2d",
   &tm_temp.tm_year, &cc, 2,
   &tm_temp.tm_mon, &cc, 2,
   &tm_temp.tm_mday, &cc, 2,
   &tm_temp.tm_hour, &cc, 2,
   &tm_temp.tm_min, &cc, 2,
   &tm_temp.tm_sec
   );

(4) 与sscanf一样,sscanf_s同样支持正则表达式

sscanf_s(stime.c_str(), "%4d%*c%2d%*c%2d%*c%2d%*c%2d%*c%2d",
  &tm_temp.tm_year, 
  &tm_temp.tm_mon, 
  &tm_temp.tm_mday, 
  &tm_temp.tm_hour, 
  &tm_temp.tm_min, 
  &tm_temp.tm_sec
  );
通过以上对比sscanf与sscanf_s的使用,可以看出后者对缓冲区安全有了更多的考虑,从而避免了许多不经意的烦恼。

大家都知道sscanf是一个很好用的函数,利用它可以从字符串中取出整数、浮点数和字符串等等。它的使用方法简单,特别对于整数和浮点数来说。但新手可 能并不知道处理字符串时的一些高级用法,这里做个简要说明吧。

    string timeIn = "2016-09-17 09:48:13.560";
tm tm_timeIn = { };
int timeOutMsecTemp = ;
sscanf_s(timeIn.c_str(), "%4d-%2d-%2d %2d:%2d:%2d.%3d",
&tm_timeIn.tm_year,
&tm_timeIn.tm_mon,
&tm_timeIn.tm_mday,
&tm_timeIn.tm_hour,
&tm_timeIn.tm_min,
&tm_timeIn.tm_sec,
&timeInMsecTemp);
tm_timeIn.tm_year -= ; //年份,指的是与1900年的差值
tm_timeIn.tm_mon -= ;     //月份,0代表1月,故应减去1
char dt[];
ctime_s(dt, sizeof dt,&time_t_In);
cout << dt << endl; //Sat Sep 17 09:48:13 2016\n
char bat[];
asctime_s(bat, sizeof bat, &tm_timeIn);
cout << bat << endl;

sscanf_强大的数据读取-转换的更多相关文章

  1. MATLAB对于文本文件(txt)数据读取的技巧总结(经典中的经典)

    振动论坛原版主eight的经典贴http://www.chinavib.com/thread-45622-1-1.html MATLAB对于文本文件(txt)进行数据读取的技巧总结(经典中的经典)由于 ...

  2. 利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model

    利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model   使用场景:网站配置项目,为了便于管理,网站有几个Model类来管理配置文件, 比如ConfigWebsiteMo ...

  3. OpenCV中IplImage图像格式与BYTE图像数据的转换

    最近在将Karlsruhe Institute of Technology的Andreas Geiger发表在ACCV2010上的Efficent Large-Scale Stereo Matchin ...

  4. TableInputFormat分片及分片数据读取源码级分析

    我们在MapReduce中TextInputFormat分片和读取分片数据源码级分析 这篇中以TextInputFormat为例讲解了InputFormat的分片过程以及RecordReader读取分 ...

  5. Java学习-028-JSON 之二 -- 数据读取

    JSON数据由 JSONObject.JSONArray.key_value 组合而成.通常来说,JSONObject 可以包含 JSONObject.JSONArray.key_value:JSON ...

  6. [SAP ABAP开发技术总结]数据输入输出转换、小数位/单位/货币格式化

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  7. 数据表转换成json(DatatableToJson)

    #region 转换Table为JSON数据 /// <summary> /// 转换Table为JSON数据 /// </summary> /// <param nam ...

  8. TensorFlow实践笔记(一):数据读取

    本文整理了TensorFlow中的数据读取方法,在TensorFlow中主要有三种方法读取数据: Feeding:由Python提供数据. Preloaded data:预加载数据. Reading ...

  9. 【强大的PDF格式转换工具】Lighten PDF Converter OCR for Mac 6.2.0

    [简介] Lighten PDF Converter OCR 是一款Mac上强大的PDF格式转换工具,可以将PDF文档快速批量的转换为Office (Word, Excel, PowerPoint), ...

随机推荐

  1. php多态简单示例

    <?php //多态由不同的人执行而产生不同的结果: //一个人通过不同的状态执行同一种动作,产生不同的结果也可称为多态 //多态的原理,就是类都写好了,不要去修改它,只要在类外的的调用参数的更 ...

  2. Xocde一次版本升级遇到的问题 (Code Sign Error)

    因为Xcode对ios版本的支持问题,我对XCode进行了一次升级,导致原来还好的项目代码出现了编译时错误. Code Sign Error failed with exit code 1 问题就在于 ...

  3. (转) JAVA中如何设置图片(图标)自适应Jlable等组件的大小

    一.问题: 一个程序,组件上设置某个图片作为图标,因为的label(应该说是组件)已经设定了固定大小, 所以再打开一些大图片时,超过组件大小的部分没显示出来,而小图片又没填充完整个组件 二.解决这个问 ...

  4. 一个windows下的ddos样本

    一个windows下的ddos样本. 加载器 程序运行之后会在临时目录释放出一个256_res.tmp的文件 之后将该文件移动至system32目录下,以rasmedia.dll命名. 删除原文件. ...

  5. keycode

    <script type="text/javascript" language=JavaScript charset="UTF-8"> docume ...

  6. JS简单解决并发量

    经常在写代码的时候碰到这样的场景:页面初始化时显示loading页,同时启动多个ajax并发请求获取数据,当每个ajax请求返回时结束loading. 举个例子,一个下订单的页面,要查询常用地址信息. ...

  7. javascript的对象

    简介: JavaScript 中的所有事物都是对象:字符串.数字.数组.日期,等等.在 JavaScript 中,对象是拥有属性和方法的数据. 一.对象的类型 本地对象:就是ECMA定义好的一些对象, ...

  8. 通过sql server 连接mysql

    图文:通过sql server 连接mysql   1.在SQL SERVER服务器上安装MYSQL ODBC驱动; 驱动下载地址:http://dev.mysql.com/downloads/con ...

  9. Tween Animation---Scale渐变尺寸缩放动画

    博主都是自己把代码测试过了才给大家分享的 在res/创建一个anim文件夹用来保存动画属性的xml 新建一个scale.xml <?xml version="1.0" enc ...

  10. JAVA 引入 junit工具框架

    我遇到的麻烦 : 开始直接按照视频上的来做,直接也是引入的他上面的jar ,但是我只引入了一个,就是上面的junit-4.4.jar,然后就会报错,会出现,空指针的错误, 后面我又按照网上的教程 这里 ...