优秀开源库uthash之utstring.h
一、简介
1.1 介绍
utstring.h中包含了一组动态string宏。使用起来非常简单,只需要将utstring.h拷贝到你的项目,并包含进你的源码即可:
#include "utstring.h"
动态字符串支持基本的:插入数据、连接、获取内容、获取长度、子字符串匹配和清除。utstring同时还可支持纯二进制数据的操作。
1.2 源码获取
utstring.h的源码可以在GitHub上直接获取(src/utstring.h):
二、使用方法
2.1 声明
动态string的数据类型是UT_string,声明如下:
UT_string *str;
2.2 new and free
声明之后,就需要使用utstring_new创建string对象,当使用完之后,再使用utstring_free释放string和内部资源。
2.3 使用
- utstring_printf和utstring_bincpy操作将数据插入到utstring;
- utstring_concat连接两个utstring;
- utstring_clear清除string的内容;
- utstring_len可以获得utstring的长度;null空字符不计算在字符串长度内;
- utstring_body可以获得utstring的内容,返回值的类型为char *,它指向的缓冲区总是以null结尾;
正是因为这样,utstring可以直接与期望字符串的外部函数一起使用。
2.4 简单的实例
简单是使用实例:
#include <stdio.h>
#include "utstring.h"
int main() {
UT_string *s;
utstring_new(s);
utstring_printf(s, "hello world!" );
printf("%s\n", utstring_body(s));
utstring_free(s);
return 0;
}
下面实例讲述了utstring_printf和utstring_concat追加字符串的方法:
#include <stdio.h>
#include "utstring.h"
int main() {
UT_string *s, *t;
utstring_new(s);
utstring_new(t);
utstring_printf(s, "hello " );
utstring_printf(s, "world " );
utstring_printf(t, "hi " );
utstring_printf(t, "there " );
utstring_concat(s, t);
printf("length: %u\n", utstring_len(s));
printf("%s\n", utstring_body(s));
utstring_free(s);
utstring_free(t);
return 0;
}
接下来的实例描述了如何将二进制文件插入string,以及如何打印和清除:
#include <stdio.h>
#include "utstring.h"
int main() {
UT_string *s;
char binary[] = "\xff\xff";
utstring_new(s);
utstring_bincpy(s, binary, sizeof(binary));
printf("length is %u\n", utstring_len(s));
utstring_clear(s);
utstring_printf(s,"number %d", 10);
printf("%s\n", utstring_body(s));
utstring_free(s);
return 0;
}
三、引用
下表列举了utstring相关的宏。
Operations | description |
---|---|
utstring_new(s) | allocate a new utstring |
utstring_renew(s) | allocate a new utstring (if s is NULL) otherwise clears it |
utstring_free(s) | free an allocated utstring |
utstring_init(s) | init a utstring (non-alloc) |
utstring_done(s) | dispose of a utstring (non-alloc) |
utstring_printf(s,fmt,…) | printf into a utstring (appends) |
utstring_bincpy(s,bin,len) | insert binary data of length len (appends) |
utstring_concat(dst,src) | concatenate src utstring to end of dst utstring |
utstring_clear(s) | clear the content of s (setting its length to 0) |
utstring_len(s) | obtain the length of s as an unsigned integer |
utstring_body(s) | get char* to body of s (buffer is always null-terminated) |
utstring_find(s,pos,str,len) | forward search from pos for a substring |
utstring_findR(s,pos,str,len) | reverse search from pos for a substring |
四、注意
4.1 new/free与init/done
使用utstring_new和utstring_free来分配和释放string。如果UT_string是静态分配的,则使用ustring_init和utstring_done来初始化和释放内部数据。
4.2 子字符串搜索
可以使用utstring_find和utstring_findR来搜索string是否包含子字符串。它有正向和反向两种类型。这两个宏总是返回子字符串在utstring中开始的偏移量,没有找到则返回-1。
比如假设utstring类型变量s包含如下数据:
ABC ABCDAB ABCDABCDABDE
那么下面的搜索将得到对应的输出结果:
utstring_find( s, -9, "ABC", 3 ) = 15
utstring_find( s, 3, "ABC", 3 ) = 4
utstring_find( s, 16, "ABC", 3 ) = -1
utstring_findR( s, -9, "ABC", 3 ) = 11
utstring_findR( s, 12, "ABC", 3 ) = 4
utstring_findR( s, 2, "ABC", 3 ) = 0
4.3 并行使用字符串搜索
如果你的程序需要对给定的字符串进行多次搜索,那么保存KMP(Knu - Morris - Pratt)表,然后在搜索之后释放会更加有效。
为了保证KMP表多次使用,请手动构建它,且将其传递给内部搜索函数。
_utstring_BuildTable (build the KMP table for a forward search)
_utstring_BuildTableR (build the KMP table for a reverse search)
_utstring_find (forward search using a prebuilt KMP table)
_utstring_findR (reverse search using a prebuilt KMP table)
下面是一个子字符串“ABC”构建正向KMP表的例子,然后在搜索中使用它:
long *KPM_TABLE, offset;
KPM_TABLE = (long *)malloc( sizeof(long) * (strlen("ABC")) + 1));
_utstring_BuildTable("ABC", 3, KPM_TABLE);
offset = _utstring_find(utstring_body(s), utstring_len(s), "ABC", 3, KPM_TABLE );
free(KPM_TABLE);
注意:内部_utstring_find的第二个参数是UT_string的长度,而不是起始位置。您可以通过向字符串开始地址添加并减去其长度来模拟位置参数。