大家好,我是杂烩君。
嵌入式大杂烩周记主要是一些实用项目学习分享,每篇一个主题。
内容主要来源于我们之前收集的资料:
https://gitee.com/zhengnianli/EmbedSummary
本期主角:sds
SDS 是 C 的字符串库,旨在通过添加堆分配的字符串来增强有限的 libc 字符串处理功能。
SDS 字符串库特点:
(1)计算效率更高。获取字符串长度所需的复杂度从O(N)降低到了O(1),所以即使获取一个非常长的字符串长度,也不会对系统性能造成任何影响,因为该命令的时间复杂度仅为O(1)。
(2)二进制安全。SDS 字符串函数是二进制安全的,因此无论内容如何,长度都是字符串的真实长度,如果字符串中间包含空字符,也没有问题。而C字符串函数遇到空字符结束。
(3)SDS 字符串函数杜绝缓冲区溢出。
(4)SDS 字符串函数减少修改字符串时带来的内存重分配次数。
(5)SDS 字符串函数兼容部分C字符串函数。
sds源码链接:
https://github.com/antirez/sds
sds的使用
1、sds结构
struct sds {
uint8_t len; /* used */
uint8_t alloc; /* excluding the header and null terminator */
unsigned char flags; /* 3 lsb of type, 5 unused bits */
char buf[];
};
用到了柔性数组,往期文章中也有用到柔性数组:
- 分享一种灵活性很高的协议格式(附代码例子)
sds字符串记录自身的len信息,获取字符串的长度的时间复杂度仅为O(1)。C字符串不记录自身的len信息,所以为了获取字符串的长度只能遍历整个字符串,并对遍历的字符进行计数,直到遇到字符串结束符为止,时间复杂度仅为O(N)。
2、sds常用接口
sds sdsnewlen(const void *init, size_t initlen);
sds sdsnew(const char *init);
sds sdsempty(void);
sds sdsdup(const sds s);
void sdsfree(sds s);
sds sdsgrowzero(sds s, size_t len);
sds sdscatlen(sds s, const void *t, size_t len);
sds sdscat(sds s, const char *t);
sds sdscatsds(sds s, const sds t);
sds sdscpylen(sds s, const char *t, size_t len);
sds sdscpy(sds s, const char *t);
(1)创建sds字符串
int main(int argc, char **argv)
{
sds mystring = sdsnew("Hello World!");
printf("%sn", mystring);
sdsfree(mystring);
return 0;
}
- sdsnew()SDS 字符串是通过函数或稍后我们将看到的其他类似函数创建和分配堆的。SDS 字符串可以printf()像任何其他 C 字符串一样传递。SDS 字符串需要用 释放sdsfree(),因为它们是堆分配的。
(2)复制sds字符串
#include <stdio.h>
#include "sds.h"
#include "sdsalloc.h"
int main(int argc, char **argv)
{
sds src_str1 = sdsnew("Hello World!");
printf("src_str1 = %sn", src_str1);
sds dst_str1 = sdsempty();
dst_str1 = sdscpy(dst_str1, src_str1);
printf("dst_str1 = %sn", dst_str1);
sdsfree(src_str1);
sdsfree(dst_str1);
return 0;
}
sdsempty()函数创建一个空的零长度字符串。
sdscpy()字符串拷贝函数,它不需要长度,但需要一个以空字符结尾的字符串。
(3)获取sds字符串长度
#include <stdio.h>
#include <string.h>
#include "sds.h"
#include "sdsalloc.h"
int main(int argc, char **argv)
{
sds str = sdsnewlen("A B",4);
printf("sdslen(str) = %dn", (int) sdslen(str));
printf("strlen(str) = %dn", (int) strlen(str));
sdsfree(str);
return 0;
}
- SDS 字符串函数是二进制安全的,因此无论内容如何,长度都是字符串的真实长度,如果字符串中间包含空字符,也没有问题。strlen函数则遇到空字符则计算结束。
(4)连接sds字符串
#include <stdio.h>
#include <string.h>
#include "sds.h"
#include "sdsalloc.h"
int main(int argc, char **argv)
{
sds str = sdsempty();
str = sdscat(str, "Hello ");
str = sdscat(str, "World!");
printf("%sn", str);
sdsfree(str);
return 0;
}
以上就是本次的分享。