天天看点

c函数sscanf的高级技巧(二)需求总结

第一篇文章 c函数sscanf高级技巧

需求

解析特定json,而不引入特定的库,如字符串

json字符串1
 "{\"ip\": [\"http://192.168.0.103:25826/description.xml\", \"http://192.168.0.112:1283/\"]}";

json字符串2
 "[{\"ip\":\"http://192.168.0.103:25826/description.xml\",\"fname\" :\"Living Room 1_5336_HiDMR\"}, 
 { \"ip\":\"http://192.168.0.112:1283/\",\"fname\" : \"涔愭挱鎶曞睆(Mr.Z)\" }]"
           

第一个是一个名为ip的数组 ,第二个是名为ip和fname的数组,我们使用方法,去除里面的空格

void remov_space(const char *body, char *newbody)
{
	//引号,冒号,前后的空格去除
	size_t len = strlen(body);
	char * pos = (char *)body;
	char * get = (char *)newbody;
	//while (*pos++ == ' ');
	for (size_t i = 0; i < len; i++)
	{
		if (*(pos) != ' ')
			*(get++) = *(pos);
		pos++;
	}
	*get = '\0';
}
           

为字符串1定义函数

bool analyselist(const char *body)
{
	char *pos = (char*)body;
	if (*pos == '{')
		pos++;
	char buffer[1024];
	if (sscanf(pos, "\"ip\":[%[^]]]}", buffer) == 1)
	{
		cout<<buffer<<endl;
		return true;
	}
	return false;
}
           
const char * x = "{\"ip\": [\"http://192.168.0.103:25826/description.xml\",\"http://192.168.0.112:1283/\"]}";
int main()
{
    char buffer[1024];
	char body[1024];
	remov_space(x, body);
	char *pos = &body[0];
	pos++;
	analyselist(&body[0]);
}
           
c函数sscanf的高级技巧(二)需求总结

找到了json字符串的数组内容,接下去就比较简单了,分割逗号就行

为字符串2 定义函数

该函数查到到有逗号的地方,并且跳过对象和数组的符号,如[ ,{

char *searchpos(const char *body)
{
	char *pos = (char*)body;
	if (*pos == '[')
		pos++;
	if (*pos == '{')
		pos++;
	char *start = pos;
	while (*pos++ != ',');
	if (*pos == '{')
		pos++;
	return pos;
}
           
const char * y = "[{\"ip\":\"http://192.168.0.103:25826/description.xml\",\"fname\" :\"Living Room 1_5336_HiDMR\"}, { \"ip\":\"http://192.168.0.112:1283/\",\"fname\" : \"涔愭挱鎶曞睆(Mr.Z)\" }]";
int main()
{
    remov_space(y, body);
	pos = &body[0]; // &buffer[0];
	const char *end = &body[0] + strlen(body);
	pos += 2;
	while (pos < end)
	{
		sscanf(pos, "\"ip\":%[^,]", buffer);
		cout << buffer << endl;
		pos = searchpos(pos);
		//cout << pos << endl;

		sscanf(pos, "\"fname\":%[^}]", buffer);
		cout << buffer << endl;
		pos = searchpos(pos);
	}
}
           
c函数sscanf的高级技巧(二)需求总结

其他

若字符串已经获取,获得像

const char * a = ““ip”:“xxxxx””;

const char * b = ““fname”:“ddddddd””;

里面的内容 xxxxx 和 ddddddd

void get_kv(const char *bodyip, const char *bodyfname, string &ipout, string &fnameout)
{
	char tmp[64];

	if (sscanf(bodyip, "\"ip\":\"%[^\"]", tmp) == 1)
		ipout = tmp;
	if (sscanf(bodyfname, "\"fname\":\"%[^\"]", tmp) == 1)
		fnameout = tmp;
}
           
int main()
{
	const char * a = "\"ip\":\"xxxxx\"";
	const char * b = "\"fname\":\"ddddddd\"";
	string a1, b1;
	get_kv(a, b, a1, b1);
	cout << a1 << " " << b1 << endl;
	return 0;
}
           
c函数sscanf的高级技巧(二)需求总结

需要截取固定长度,可以加上%n,这种模式来截取需要的字符

bool AnalyseList(const char *body)
{
	//{"ip":["http://192.168.0.103:25826/description.xml", "http://192.168.0.112:1283/"]}
	char buffer[128];
	if (sscanf(body, "{\"ip\":%9[^,]", buffer) == 1)
	{
		printf(buffer);
	}

	return true;
}
           

总结

使用sscanf和c的计算结合,我们可以解析很多我们需要解析的字符串,如json,如果足够简单,没有必要引入json的库,多写一写,想一想,逻辑、数据结构、算法就会慢慢进入我们的视野