C语言实现像高级语言一样的字符串操作(一)

如何用C语言操作字符串,像高级语言一样灵活的操作,字符串的长度任意变呢?答案是肯定的,而且更灵活,效率更高!

下面实现strcpy与strcat函数的结合体

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define MEM_ALINE 64//预留量,为了减少内存分配次数
 
//定义结构体,声明变量的时候必须要赋初值
//比如string str={0,0,0};
typedef struct{
    size_t memlen;//内存长度
    size_t strlen;//字符长度
    char* str;//字符串,后面有'\0'
}string;
 
//本模块所有的函数在变量不用时,都需要释放内存
void str_free(string *src)
{
    if(src->memlen){//如果已经申请过了内存
        src->memlen=src->strlen=0;
        free(src->str);
    }
}
 
//构建字符串,sour字符串在定义string t1={0,0,0};必须要初始化成0
//因为第二次要用realloc函数分配内存了
//本函数支持strcpy_free(&t1,t1.str,3);也就是说把自边往后移3位
//函数名后面加_free表示提醒程序员不要忘了用str_free函数释放内存
void strcpy_free(string *dest,char *sour,size_t start)
{
    char *src=sour;//定义新变量,用于自身复制到自身时
    size_t len=strlen(src)+1;//新字符的长度
    if(start>dest->strlen)start=dest->strlen;//如果传入的起始位置大于原来的长度
    if(len==1){//如果src="",可以直接用desc->str[xx]=0;与dest->strlen=start;来代替
        if(dest->strlen){//原来有内容
            dest->str[start]=0;
            dest->strlen=start;
        }
    }
    else{
        int isFree=0;//是否需要释放内存
        if(dest->memlen==0){//如果第1次赋值
            len+=start;//整长度加上起始位置
            dest->strlen=len-1;//字符长度
            dest->str=(char*)malloc(len);//分配内存
            dest->memlen=len;//内存长度
            strcpy(&dest->str[start],src);//复制字符串
        }
        else{
            if(src>=dest->str && src<=dest->str+start){//内存地址有重叠,可能是自身复制到自身
                src=(char*)malloc(len);//分配原来的长度
                strcpy(src,sour);//先把原来的数据复制到临时变量中
                isFree=1;//需要释放临时分配的内存
            }
 
            len+=start;//整长度加上起始位置
            dest->strlen=len-1;//字符长度
            if(dest->memlen<len){//内存扩容
                len+=MEM_ALINE;//多分配预留量
                dest->memlen=len;//内存长度
                dest->str=(char*)realloc(dest->str,len);//扩容内存
            }
 
            strcpy(&dest->str[start],src);//复制字符串
        }
 
        if(len+(MEM_ALINE<<1)<=dest->memlen){//如果新内存空间,比原来小2倍预留量
            dest->memlen=len+MEM_ALINE;//为了节省了内存空间,保留预留量后释放多余内存
            dest->str=(char*)realloc(dest->str,dest->memlen);
        }
 
        if(isFree)free(src);//释放临时分配的内存
    }
}
 
int main(int argc,char*argv[])
{
    string t1={0,0,0};
 
 
    //1.连接两个字符串
    strcpy_free(&t1,"Hello! My Good ",0);
    printf("%s\n",t1.str);
    strcpy_free(&t1,"Friends.~~",t1.strlen);
    printf("%s\n",t1.str);
    strcpy_free(&t1,t1.str,7);
    printf("%s\n",t1.str);
    strcpy_free(&t1,"abcd",1);
    printf("%s\n",t1.str);
 
    str_free(&t1);//释放内存
}

程序运行的结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值