sscanf和sscanf_s 函数解析

sscanf 和 sscanf_s 测试代码

#include <string>
#include <stdio.h>
#include <iostream>

int main(int argc, char** argv){
	//sscanf
	char str[512] = {0};
	//取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
	sscanf("123456 ", "%4s", str);
	printf("str=%s\n", str);

	//取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。
	sscanf("123456 abcdedf", "%[^ ]", str);
	printf("str=%s\n", str);

	//取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。
	sscanf("123456abcdedfBCDEF", "%[1-9a-z]", str);
	printf("str=%s\n", str);

	//取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。
	sscanf("123456abcdedfBCDEF", "%[^A-Z]", str);
	printf("str=%s\n", str);

	char cc;
	tm tm_temp = { 0 };
	std::string stime("2009-01-02_11:12:13");
	//必须严格按照分隔符形式匹配填写,若遇到不匹配项则终止解析
	int num = 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
		);
	std::cout << num << " "<< tm_temp.tm_year << " " << tm_temp.tm_mon << " " << tm_temp.tm_mday << " "
		<< tm_temp.tm_hour << " " << tm_temp.tm_min << " " << tm_temp.tm_sec << std::endl;

	//可以不按照分割符号形式填写,字符数必须一致,例如可以正确解析“2009/01/02_11:12:13”
	stime = "2009/01/02_11:12:13";
	num = 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
		);
	std::cout << num << " " << tm_temp.tm_year << " " << tm_temp.tm_mon << " " << tm_temp.tm_mday << " "
		<< tm_temp.tm_hour << " " << tm_temp.tm_min << " " << tm_temp.tm_sec << std::endl;

	//可以不按照分割符号形式填写,字符数必须一致,同上, %1s可以等同于 %c
	num = 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
	);
	std::cout << num << " " << tm_temp.tm_year << " " << tm_temp.tm_mon << " " << tm_temp.tm_mday << " "
		<< tm_temp.tm_hour << " " << tm_temp.tm_min << " " << tm_temp.tm_sec << std::endl;
	
	//可以不按照分割符形式和数量填写,类型必须一致,例如可以正确解析“2009/01/02___11:12:13”
	//这里使用了sscanf的正则表达式,与通用的正则表示类似但不完全相同,%*c表示忽略连续多个字符
	stime = "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,
		&tm_temp.tm_mon,
		&tm_temp.tm_mday,
		&tm_temp.tm_hour,
		&tm_temp.tm_min,
		&tm_temp.tm_sec
		);
	std::cout << num << " " << tm_temp.tm_year << " " << tm_temp.tm_mon << " " << tm_temp.tm_mday << " "
		<< tm_temp.tm_hour << " " << tm_temp.tm_min << " " << tm_temp.tm_sec << std::endl;

	//sscanf_s
	stime = "2009-01-02_11:12:13";

	//与sscanf第一种方法相同,可以使用"%4d-%2d-%2d_%2d:%2d:%2d"格式匹配解析
	num = 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
		);
	std::cout << num << " " << tm_temp.tm_year << " " << tm_temp.tm_mon << " " << tm_temp.tm_mday << " "
		<< tm_temp.tm_hour << " " << tm_temp.tm_min << " " << tm_temp.tm_sec << std::endl;

	//使用%c格式对数据解析时,必须对相应的缓冲区增加长度参数,否则将会出错
	num = 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
		);
	std::cout << num << " " << tm_temp.tm_year << " " << tm_temp.tm_mon << " " << tm_temp.tm_mday << " "
		<< tm_temp.tm_hour << " " << tm_temp.tm_min << " " << tm_temp.tm_sec << std::endl;

	//使用%s格式对数据解析时,缓冲长度必须大于字符串长度,否则不予解析
	num = 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
		);
	std::cout << num << " " << tm_temp.tm_year << " " << tm_temp.tm_mon << " " << tm_temp.tm_mday << " "
		<< tm_temp.tm_hour << " " << tm_temp.tm_min << " " << tm_temp.tm_sec << std::endl;

	//与sscanf一样,sscanf_s同样支持正则表达式
	stime = "2009/01/02___11:12:13";
	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
		);
	std::cout << num << " " << tm_temp.tm_year << " " << tm_temp.tm_mon << " " << tm_temp.tm_mday << " "
		<< tm_temp.tm_hour << " " << tm_temp.tm_min << " " << tm_temp.tm_sec << std::endl;

	getchar();
	return 0;
}

输出信息如下

str=1234
str=123456
str=123456abcdedf
str=123456abcdedf
6 2009 1 2 11 12 13
11 2009 1 2 11 12 13
11 2009 1 2 11 12 13
11 2009 1 2 11 12 13
6 2009 1 2 11 12 13
11 2009 1 2 11 12 13
11 2009 1 2 11 12 13
11 2009 1 2 11 12 13

参考

  1. sscanf,sscanf_s及其相关用法
  2. C语言中sscanf()函数的字符串格式化用法
  3. sscanf正则表达式(二)
posted @ 2021-11-09 13:59  采男孩的小蘑菇  阅读(955)  评论(0编辑  收藏  举报