加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 本期主角:sds
    • sds的使用
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

嵌入式大雜燴周記:sds 字符串庫(kù)

2022/08/26
670
閱讀需 9 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

大家好,我是雜燴君。

嵌入式大雜燴周記主要是一些實(shí)用項(xiàng)目學(xué)習(xí)分享,每篇一個(gè)主題。

內(nèi)容主要來(lái)源于我們之前收集的資料:

https://gitee.com/zhengnianli/EmbedSummary

本期主角:sds

SDS 是 C 的字符串庫(kù),旨在通過(guò)添加堆分配的字符串來(lái)增強(qiáng)有限的 libc 字符串處理功能。

SDS 字符串庫(kù)特點(diǎn):

(1)計(jì)算效率更高。獲取字符串長(zhǎng)度所需的復(fù)雜度從O(N)降低到了O(1),所以即使獲取一個(gè)非常長(zhǎng)的字符串長(zhǎng)度,也不會(huì)對(duì)系統(tǒng)性能造成任何影響,因?yàn)樵撁畹臅r(shí)間復(fù)雜度僅為O(1)。

(2)二進(jìn)制安全。SDS 字符串函數(shù)是二進(jìn)制安全的,因此無(wú)論內(nèi)容如何,長(zhǎng)度都是字符串的真實(shí)長(zhǎng)度,如果字符串中間包含空字符,也沒(méi)有問(wèn)題。而C字符串函數(shù)遇到空字符結(jié)束。

(3)SDS 字符串函數(shù)杜絕緩沖區(qū)溢出。

(4)SDS 字符串函數(shù)減少修改字符串時(shí)帶來(lái)的內(nèi)存重分配次數(shù)。

(5)SDS 字符串函數(shù)兼容部分C字符串函數(shù)。

sds源碼鏈接:

https://github.com/antirez/sds

sds的使用

1、sds結(jié)構(gòu)

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[];
};

用到了柔性數(shù)組,往期文章中也有用到柔性數(shù)組:

  • 分享一種靈活性很高的協(xié)議格式(附代碼例子)

sds字符串記錄自身的len信息,獲取字符串的長(zhǎng)度的時(shí)間復(fù)雜度僅為O(1)。C字符串不記錄自身的len信息,所以為了獲取字符串的長(zhǎng)度只能遍歷整個(gè)字符串,并對(duì)遍歷的字符進(jìn)行計(jì)數(shù),直到遇到字符串結(jié)束符為止,時(shí)間復(fù)雜度僅為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)創(chuàng)建sds字符串
int main(int argc, char **argv)
{
    sds mystring = sdsnew("Hello World!");
    printf("%sn", mystring);
    sdsfree(mystring);

    return 0;
}

 

 

  • sdsnew()SDS 字符串是通過(guò)函數(shù)或稍后我們將看到的其他類似函數(shù)創(chuàng)建和分配堆的。SDS 字符串可以printf()像任何其他 C 字符串一樣傳遞。SDS 字符串需要用 釋放sdsfree(),因?yàn)樗鼈兪嵌逊峙涞摹?/li>
 
(2)復(fù)制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()函數(shù)創(chuàng)建一個(gè)空的零長(zhǎng)度字符串。

sdscpy()字符串拷貝函數(shù),它不需要長(zhǎng)度,但需要一個(gè)以空字符結(jié)尾的字符串。

(3)獲取sds字符串長(zhǎng)度
#include <stdio.h>
#include <string.h>
#include "sds.h"
#include "sdsalloc.h"

int main(int argc, char **argv)
{
    sds str = sdsnewlen("A