天天看点

关于scanf、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的使用,可以看出后者对缓冲区安全有了更多的考虑,从而避免了许多不经意的烦恼。

文章转自http://blog.csdn.net/shellching/article/details/4958518