1.
void strbuf_init(struct strbuf *sb, size_t alloc); |
这个函数要做到对原本的结构体进行初始化操作,同时做到对其中的容量进行初始化的定义,那么可以通过对其中的每一个所含部分进行初始化的操作,重要的是注意其中的那个荣里那个的问题,同时记得对缓冲区的字符串进行定义,即需要的是alloc字符串的长度加上最后的\0的部分,所以可以得到代码
void strbuf_init(struct strbuf*sb,size_t alloc){
sb->len=0;
sb->alloc=alloc;
if(alloc)
sb->buf=(char*)malloc(sizeof(char)*(alloc+1));
}
2.void strbuf_attach(struct strbuf*sb,void*str,size_t len,size_t alloc){
这个函数的作用是对字符串起到一个填充的作用,因为在前面一个函数当中,已经完成了容量的设定,而且也没有发生容量的改变,那么这里就可以减少一部分的操作,只需要将字符串填充进入结构体当中即可,最后因为进入的是一个一个字节的进入,所以需要在字节数荣结束之后加上一个\0用来确保输入的就是原本的样子
void strbuf_attach(struct strbuf*sb,void*str,size_t len,size_t alloc){
sb->alloc=alloc;
sb->len=len;
sb->buf=(char*)str;
sb->buf[sb->len]='\0';
}
sb->buf=(char*)str;
其中这一步进行输入数据。
3. void strbuf_release(struct strbuf*sb){
这里是要做到对其中的内存进行一个释放的操作,有两种方法操作,第一种是直接进行操作,对其中缓冲区的元素进行直接释放即free(sb->buf)即可,第二种是进行一个判断,如果灵敏啊可以容纳的字符串数量为0或者他本来就是空的时候,直接退出这个函数,用来减少时间的浪费
void strbuf_release(struct strbuf*sb){
if(sb->alloc==0||sb==NULL)
{return;}
free(sb->buf);
}
4.void strbuf_swap(struct strbuf*a,struct strbuf*b){
swap这个函数和之前在学习函数的时候哦学习到的交换相同,都是进行了一个修改其中地址的操作。
将其中的每一个部分进行交换,切记要格外设定一个变量,用于第一轮交换结束之后的交换。
那么便可以得到代码。
int az,aq=0;
az=a->len;
a->len=b->len;
b->len=az;
aq=a->alloc;
a->alloc=b->alloc;
b->alloc=aq;
char*c;
c=a->buf;
a->buf=b->buf;
b->buf=c;
5.char*strbuf_detach(struct strbuf *sb,size_t *sz){
这个函数的作用是将其中的内存取出来然后将sz设置成为alloc的大小,这里要注意到这里给了两个地址,用来确保得到两个部分用于给予大小。
那么第一步可以做到将其字符串进行给予ptr,即一个新定义的变量地址,然后即可对其进行输出,然后需要使用到之前函数的内容。
*sz=sb->alloc;
strbuf_init(sb,0);
char*ptr=sb->buf;
return ptr;
6.int strbuf_cmp(const struct strbuf*first,const struct strbuf*second){
这个函数可以在很短的情况下结束,我们已经知道里那个两个 strbuf的大小等各种信息,那么就可以通过直接对其进行return ,这正常情况应该直接出来,但如果没有做到,说明这并不是正常情况,即可以判读。
return first->len-second->len;
7. void strbuf_reset(struct strbuf*sb){
这个要求是晴空这个结构体中的东西,所以可以将其中缓冲区 的东西进行一个删除或者是改写成为\0.所以可以使用for循环,对其最开始到最后的部分进行改写。
for(int a=0;a<sb->len;a++){
*((sb->buf)+a)='\0';
}
sb->len=0;
8.void strbuf_grow(struct strbuf*sb,size_t extra){
这里是要做到输入之后起码的字节的空闲空间。那么便可以先对这个原本空间进行一个判断。如果大于所需要的即可以直接退出,但如果不到则需要对其空间进行扩容。那么这个函数便可以得到
if(sb -> len + extra < sb -> alloc) return;
if(sb -> alloc == 0)
sb->buf = NULL;
sb -> buf = (char*)realloc(sb -> buf, sb -> len + extra + 1);
sb -> alloc = sb->len + extra + 1;
if(sb -> alloc == 0) sb->buf[0]='\0';
9-11:
这几个都是对其追加数据,无非是其长度不同罢了。重要的还书对于函数需要的内存是否和其与原本需要的高出或者相同。对于追加数据的可以直接用for循环对其中的数据进行写入。
所以可以将其放到一起进行讨论。
if(sb->len+len>sb->alloc)
{
strbuf_grow(sb,len+1);
}
for(int i = 0;i < len ;i++)
{
sb->buf[sb->len+i] = ((char *)data)[i];
}
sb->len=len+sb->len;
sb->buf[sb->len]='\0';
strbuf_grow(sb,2);
sb->buf[sb->len]=c;
sb->len++;
sb->buf[sb->len]='\0';
strbuf_grow(sb,strlen(s)+1);
memcpy(sb->buf+sb->len,s,strlen(s));
sb->len=sb->len+strlen(s);
sb->buf[sb->len]='\0';
12.void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2){
这个函数说是话和上面几个函数也有一定的相似的地方。同样要先通过grow函数进行一个数据在空间上的足够存放。将sb结构体中的len进行一个扩大,最后在数据全部写入之后,将这个\0输入到数据的最后面。
strbuf_grow(sb,sb2->len+1);
memcpy(sb->buf+sb->len,sb2->buf,sb2->len);
sb->len=sb->len+sb2->len;
sb->buf[sb->len]='\0';
13.void strbuf_setlen(struct strbuf *sb, size_t len){
这个设置长度为len也比较好做,直接让len里面的为len即可,但要在最后buf的时候,注意\0的存在
sb->len=len;
sb->buf[len]='\0';
14.size_t strbuf_avail(const struct strbuf *sb){
这个可以相似于上面计算是否相同的那个函数,直接return 即可
return sb->alloc-sb->len-1;