佛山网站建设公司点精小胡,合肥如何做百度的网站,免费咨询的英文,建网站必须要服务器吗文章目录初始化字符串字符串基本操作字符串拼接操作other获取指定范围里的字符串将字符串中的所有字符均转为小写的形式将字符串中所有字符均转为大写的形式字符串比较other#define SDS_ABORT_ON_OOM#include sds.h
#include stdio.h
#include stdlib.…
文章目录初始化字符串字符串基本操作字符串拼接操作other获取指定范围里的字符串将字符串中的所有字符均转为小写的形式将字符串中所有字符均转为大写的形式字符串比较other#define SDS_ABORT_ON_OOM#include sds.h
#include stdio.h
#include stdlib.h
#include stdarg.h
#include string.h
#include ctype.h
#include zmalloc.h//内存出错函数**封装的一个报错函数
static void sdsOomAbort(void) {//发生内存错误时向标准输出设备输出出错信息fprintf(stderr,SDS: Out Of Memory (SDS_ABORT_ON_OOM defined)\n);abort();//出错时直接终止程序
}初始化字符串
//新建一个字符串并将其初始化初始化时取init字符串中initlen个字符
sds sdsnewlen(const void *init, size_t initlen) {struct sdshdr *sh;//创建字符串存储空间多创建一个1是因为C语言中的字符串//均有一个\0结束符sh zmalloc(sizeof(struct sdshdr)initlen1);
#ifdef SDS_ABORT_ON_OOM//如果内存分配失败的情况下直接终止程序的运行if (sh NULL) sdsOomAbort();
#else//如果内存分配失败的情况下返回NULLif (sh NULL) return NULL;
#endif//记录内存空间的实际使用量sh-len initlen;//记录内存空间的余下多少sh-free 0;if (initlen) {//如果设置了init的情况下复制initlen个字符if (init) memcpy(sh-buf, init, initlen);//否则将内存全部置为0else memset(sh-buf,0,initlen);}//结尾字符,C语言中字符串均以\0结尾sh-buf[initlen] \0;return (char*)sh-buf;
}//生成一个空字符串,调用newlen()函数开辟0个长度
sds sdsempty(void) {return sdsnewlen(,0);
}/** 生成一个新字符串* init表字生成新字符串时要拷贝进来的东西* 计算传进来的字符串长度然后调用sdsnewlen()函数*/
sds sdsnew(const char *init) {size_t initlen (init NULL) ? 0 : strlen(init);//传入 init的值init的长度//返回的是//返回sdshdr这个结构体的return (char*)sh-buf;字符串长度return sdsnewlen(init, initlen);
}字符串基本操作
/** 获取字符串的长度* 字符串的长度是存放在sdshdr结构中的len里面*/
size_t sdslen(const sds s) {struct sdshdr *sh (void*) (s-(sizeof(struct sdshdr)));return sh-len;
}/** 对字符串进行复制*/
sds sdsdup(const sds s) {return sdsnewlen(s, sdslen(s));
}/** 释放字符串*/
void sdsfree(sds s) {if (s NULL) return;zfree(s-sizeof(struct sdshdr));
}/** 返回字符串中还有多少空间可以使用*/
size_t sdsavail(sds s) {struct sdshdr *sh (void*) (s-(sizeof(struct sdshdr)));return sh-free;
}/** 更新字符串的长度*/
void sdsupdatelen(sds s) {struct sdshdr *sh (void*) (s-(sizeof(struct sdshdr)));int reallen strlen(s);sh-free (sh-len-reallen);sh-len reallen;
}/** 给字符串增加长度*/
static sds sdsMakeRoomFor(sds s, size_t addlen) {struct sdshdr *sh, *newsh;size_t free sdsavail(s);size_t len, newlen;//如果余下空间还足够的话if (free addlen) return s;len sdslen(s);sh (void*) (s-(sizeof(struct sdshdr)));newlen (lenaddlen)*2;newsh zrealloc(sh, sizeof(struct sdshdr)newlen1);//内存分配失败的情况下进行处理
#ifdef SDS_ABORT_ON_OOMif (newsh NULL) sdsOomAbort();
#elseif (newsh NULL) return NULL;
#endif//新的余下空间newsh-free newlen - len;return newsh-buf;
}字符串拼接操作
//进行字符串的拼接操作
sds sdscatlen(sds s, void *t, size_t len) {struct sdshdr *sh;size_t curlen sdslen(s);s sdsMakeRoomFor(s,len);if (s NULL) return NULL;sh (void*) (s-(sizeof(struct sdshdr)));memcpy(scurlen, t, len);sh-len curlenlen;sh-free sh-free-len;s[curlenlen] \0;return s;
}//同样进行字符串的拼接操作
sds sdscat(sds s, char *t) {return sdscatlen(s, t, strlen(t));
}//进行字符串的copy,会覆盖掉原字符串
sds sdscpylen(sds s, char *t, size_t len) {struct sdshdr *sh (void*) (s-(sizeof(struct sdshdr)));//字符串s代表的字符串的总共长度size_t totlen sh-freesh-len;if (totlen len) {s sdsMakeRoomFor(s,len-totlen);if (s NULL) return NULL;sh (void*) (s-(sizeof(struct sdshdr)));totlen sh-freesh-len;}memcpy(s, t, len);s[len] \0;sh-len len;sh-free totlen-len;return s;
}//同样也是进行字符串的copy
//也会覆盖掉原字符串
sds sdscpy(sds s, char *t) {return sdscpylen(s, t, strlen(t));
}//格式化拼接字符串
sds sdscatprintf(sds s, const char *fmt, ...) {va_list ap;char *buf, *t;size_t buflen 32;while(1) {buf zmalloc(buflen);
#ifdef SDS_ABORT_ON_OOMif (buf NULL) sdsOomAbort();
#elseif (buf NULL) return NULL;
#endifbuf[buflen-2] \0;//c语言中的可变参数的循环遍历va_start(ap, fmt);vsnprintf(buf, buflen, fmt, ap);va_end(ap);if (buf[buflen-2] ! \0) {zfree(buf);buflen * 2;continue;}break;}//对字符串进行拼接t sdscat(s, buf);zfree(buf);return t;
}other
//字符串中去掉首尾包含cset里的字符
sds sdstrim(sds s, const char *cset) {struct sdshdr *sh (void*) (s-(sizeof(struct sdshdr)));char *start, *end, *sp, *ep;size_t len;//字符串的开始位置sp start s;//字符串的结束位置ep end ssdslen(s)-1;//查看字符串cset中首次出现字符*sp的位置while(sp end strchr(cset, *sp)) sp;//查找字符串cset中首次出现字符*ep的位置while(ep start strchr(cset, *ep)) ep--;len (sp ep) ? 0 : ((ep-sp)1);//字符串的内存移动操作if (sh-buf ! sp) memmove(sh-buf, sp, len);sh-buf[len] \0;//字符串的余下空间增长sh-free sh-free(sh-len-len);sh-len len;return s;
}获取指定范围里的字符串
sds sdsrange(sds s, long start, long end) {struct sdshdr *sh (void*) (s-(sizeof(struct sdshdr)));size_t newlen, len sdslen(s);if (len 0) return s;if (start 0) {start lenstart;if (start 0) start 0;}if (end 0) {end lenend;if (end 0) end 0;}newlen (start end) ? 0 : (end-start)1;if (newlen ! 0) {if (start (signed)len) start len-1;if (end (signed)len) end len-1;newlen (start end) ? 0 : (end-start)1;} else {start 0;}if (start ! 0) memmove(sh-buf, sh-bufstart, newlen);sh-buf[newlen] 0;sh-free sh-free(sh-len-newlen);sh-len newlen;return s;
}将字符串中的所有字符均转为小写的形式
void sdstolower(sds s) {int len sdslen(s), j;for (j 0; j len; j) s[j] tolower(s[j]);
}将字符串中所有字符均转为大写的形式
void sdstoupper(sds s) {int len sdslen(s), j;for (j 0; j len; j) s[j] toupper(s[j]);
}字符串比较
//对两个字符串进行比较
int sdscmp(sds s1, sds s2) {size_t l1, l2, minlen;int cmp;l1 sdslen(s1);l2 sdslen(s2);minlen (l1 l2) ? l1 : l2;//返回短的cmp memcmp(s1,s2,minlen);//该函数返回一个指向目标存储区s1的指针。if (cmp 0) return l1-l2;//两者不相等cmp0return cmp;
}
other
/* Split s with separator in sep. An array* of sds strings is returned. *count will be set* by reference to the number of tokens returned.** On out of memory, zero length string, zero length* separator, NULL is returned.** Note that sep is able to split a string using* a multi-character separator. For example* sdssplit(foo_-_bar,_-_); will return two* elements foo and bar.** This version of the function is binary-safe but* requires length arguments. sdssplit() is just the* same function but for zero-terminated strings.*/
sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count) {int elements 0, slots 5, start 0, j;//开设5字节的内存空间//实际开设时会开设6字节具体可以参看zmallo.c里的源代码sds *tokens zmalloc(sizeof(sds)*slots);
#ifdef SDS_ABORT_ON_OOMif (tokens NULL) sdsOomAbort();
#endifif (seplen 1 || len 0 || tokens NULL) return NULL;for (j 0; j (len-(seplen-1)); j) {/* make sure there is room for the next element and the final one */if (slots elements2) {sds *newtokens;slots * 2;newtokens zrealloc(tokens,sizeof(sds)*slots);if (newtokens NULL) {
#ifdef SDS_ABORT_ON_OOMsdsOomAbort();
#elsegoto cleanup;
#endif}tokens newtokens;}/* search the separator */if ((seplen 1 *(sj) sep[0]) || (memcmp(sj,sep,seplen) 0)) {//计算分割符以前的字符串的长度tokens[elements] sdsnewlen(sstart,j-start);if (tokens[elements] NULL) {
#ifdef SDS_ABORT_ON_OOMsdsOomAbort();//失败的情况下如果定义了内存失败函数将直接调用
#elsegoto cleanup;//否则跳到cleanup函数进行一个一个的释放
#endif}elements;start jseplen;j jseplen-1; /* skip the separator */}}/* Add the final element. We are sure there is room in the tokens array. *///分割串里面的最后一个字符串tokens[elements] sdsnewlen(sstart,len-start);if (tokens[elements] NULL) {
#ifdef SDS_ABORT_ON_OOMsdsOomAbort();
#elsegoto cleanup;
#endif}elements;//传的是个引用可以获取最终分割为多少个数组*count elements;return tokens;#ifndef SDS_ABORT_ON_OOM
//如果没有定义分配失败的情况下内存操作函数
//将会一个一个的调用内存失败处理函数
cleanup:{int i;for (i 0; i elements; i) sdsfree(tokens[i]);zfree(tokens);return NULL;}
#endif
}