今天遇到了两个比较有意思的函数,可以将字符串分割,在项目中一般用的比较多吧,记录一下,防止只有自己忘记。一般来说都是自定义函数返回的字符串需要分割保存在数据库之类的功能,于是就需要用到这些函数,分割然后保存在不同的buf中,在实现保存之类的。
1- strtok()函数
char *strtok(char *str, const char *delim);
str是你想要分割的字符串,delim是以什么字符分割,我们代码举例来了解:
#include <string.h>
#include <stdio.h>
int main (int argc, char *argv[])
{
char str[80] = "GD001/2022-10-11/18:62:37/37.52142摄氏度";
const char s[2] = "/"; //字符串里可以是一个分隔符,也可以是分隔符的集合
char *token;
/* 获取第一个子字符串 */
token = strtok(str, s);
/* 继续获取其他的子字符串 */
while( token != NULL )
{
printf( "%s\n", token );
/*默认为上一个未分割完的字符串*/
token = strtok(NULL, s);
}
return 0;
}
运行结果:
2- sscanf()函数
这个函数的功能比较多,但是我还是讲一下和strtok()函数差不多的功能,因为自己在这一方面用到了,还是先来看代码:
int sscanf(const char *str, const char *format, ...);
#include<stdio.h>
int main(int argc, char *argv[])
{
char device[15];
char date[15];
char time[15];
char temper[10];
char buf[512] = "GD002/2022-10-11/18:52:15/35.4941摄氏度";
int ret = sscanf(buf, "%05s %*01s %10s %*01s %08s %*01s %s", device, date, time, temper);
printf("device:%s\n", device);
printf("data:%s\n", date);
printf("time:%s\n", time);
printf("temper:%s\n", temper);
return 0;
}
这个主要就是将主字符串分成自己想要的部分保存在buf中,然后利用”%*01s“表示的是下一个读到的这一个字符串忽略不要。
运行结果:
3- sqlite3_mprintf()函数
sqlite3数据库中比较好的一个连接字符串的函数可以看看。如果是要将数据保存到数据库中,因为数据库中有不同的列,于是需要分别保存进去。上面的两个函数用到之后,就可以将分割的数据直接保存进去啦!
主要看第93行,怎么讲数据插入进去的。
89 /*插入数据*/
90 char *rt;
91 char *port="12345";
92 char *temper="31.0000摄氏度";
93 rt = sqlite3_mprintf("INSERT INTO temper VALUES(NULL,'%s','%s','%s')", port, buf, temper);//插入数据准备
94 rc = sqlite3_exec(db, rt, 0, 0, &p2);//执行命令
95 if(rc != SQLITE_OK)
96 {
97 printf("Insert data faliure:%s\n", strerror(errno));
98 }
4- 不同时来的多个buf信息保存在一个buf中
在我们的项目或者实践中,经常会遇见一个问题,就是我们需要将每次读到的数据放到上一次读到数据后面,我们来看看怎么操作的。
我们设置一个变量计数,用来表示现在总共收到了多少个字节的数据到buffer中,snprintf返回的是写进去的值,于是我们就可以在每次的ofset+rv,即可。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int ofset = 0;
int rv;
char together_buf[10];
char *buf[3] = {"He","ll","o!"};
printf("buf[0]:%s\n", buf[0]);
printf("buf[1]:%s\n", buf[1]);
printf("buf[2]:%s\n", buf[2]);
for(int i=0; i<3; i++)
{
rv = snprintf(together_buf+ofset, sizeof(together_buf)-ofset, "%s", buf[i]);
printf("ofset:%d rv:%d\n", ofset, rv);
ofset += rv;
}
printf("togeter_buf:%s\n", together_buf);
return 0;
}
结果:
./a.out
buf[0]:He
buf[1]:ll
buf[2]:o!
ofset:0 rv:2
ofset:2 rv:2
ofset:4 rv:2
togeter_buf:Hello!
#include <string.h>
#include <stdio.h>
void a(char *str);
int main (int argc, char *argv[])
{
char str[80] = "GD001|2022-10-11|18:62:37|37.52142摄氏度";
a(str);
return 0;
}
void a(char *str)
{
char *token=NULL;
char buf[80];
const char s[2] = "|";
int ofset =0;
/* 获取第一个子字符串 */
token = strtok(str, s);
/* 继续获取其他的子字符串 */
while( token != NULL )
{
int rv = snprintf(buf+ofset, sizeof(buf)-ofset, "%s ", token);
//strncat();
printf( "%s\n", token );
/*默认为上一个未分割完的字符串*/
token = strtok(NULL, s);
ofset+=rv;
}
printf("%s\n", buf);
}
./a.out
GD001
2022-10-11
18:62:37
37.52142摄氏度
GD001 2022-10-11 18:62:37 37.52142摄氏度