c语言实现字符串替换

2020-03-29  本文已影响0人  雪狼老巫

网上搜了一把,发现搜到的字符串替换方法都是把字符串的长度写死的,这样的话对长字符串替换就存在问题。所以今天就搞一个没有长度限制的字符串替换方法。

c语言小白,总结过程中遇到的问题,以点带面,大神请见谅。

首先总结一下问题点和知识点

1.字符串和字符数组的区别

2.malloc分配内存会不会修改内存中的内容

3.函数内部对形参的修改是否会影响函数外部的内容

接下来贴代码:

void replaceString(char *src, char *findchar , char *repchar)

{

    printf("::%s\n", src);

    printf("find char is::%s\n", findchar);

    printf("repchar is::%s\n", repchar);

    char *findlen;

    char *dest;

    while ((findlen = strstr(src, findchar)))    //查找src中第一个出现findchar

    {

        char *tmp = (char *)malloc(strlen(src) + (strlen(repchar) - strlen(findchar)) + 1);//申请一个新的内存可以放下替换后的字符串

        //memcpy(tmp, "\0", strlen(tmp));

        strncpy(tmp, src, findlen - src);//把替换字符前面的拷贝

        tmp[findlen - src] = '\0';//赋值一个结尾符,下面会说原因

        strcat(tmp, repchar);//追加替换的内容

        strcat(tmp, findlen + strlen(findchar));//追加之后要替换内容之后的字符串

        src = strdup(tmp);//临时地址拷贝给src

        free(tmp);//释放临时变量

    }

    printf("::%s\n", src);

    //return null;

}

思考

        这种方式每查找到一次替换都要执行两次的申请内存操作,是否影响性能,有没有好的方法?各位有好的方法欢迎指教。

1.字符串和字符数组的区别

字符串和字符数组是不同的两个概念。char *str = "abc"和char str[] = {'a','b','c'}是完全不同的。

(1)字符串是以第一个'\0'结尾的一串字符。

(2)字符数组是一个固定长度的数组,数组里面存放的是字符。

直观举个例子,“abc\0db”这个是可以存放到字符数组里面的。并且取出来也一样。但是如果放到字符串中的话,取出来就是“adc”了。因为字符串检测到'\0'就认为字符串结束了。

【注】

char *str = "abc" 中变量str存放在栈中,而变量str指向的内容存放在数据段中,因为"abc"是数据段中的字符串常量,是只读的不可以修改,所以执行str[0]='b'会报错。str实际长度是4,在abc后面还有一个'\0'。sizeof(str)是4,strlen(str)是3。

char str[]={"abc"}。虽然是字符数组但是他的长度(sizeof)实际是4,因为“abc”是一个字符串,字符串后面是有'\0'的。但是strlen(str)得到的结果还是3的。

参考:http://c.biancheng.net/view/337.html

有两个知识点。一个是字符串和字符数组的(上面知识点),另一个是内存划分的。

可执行程序在内存运行时由栈、堆、数据段、代码段组成。

栈:由编译器自动生成和释放,存放的是函数的参数值,局部变量等

堆:有代码生成和释放,一定要释放,否则内存泄漏。通过malloc等方式生成内存

数据段:分为只读的,已初始化读写的。未初始化读写的。只读的是一些常量,const修饰的。已初始化读写的是初始化的全局变量或者静态变量。未初始化读写的是未初始化的全局变量或静态变量。

代码段:是二进制代码的存储区。

参考:https://blog.csdn.net/weixin_39964178/article/details/82875304

https://blog.csdn.net/Filter_CPH/article/details/48524249

2.malloc分配内存会不会修改内存中的内容

malloc分配内存会不会修改内存中的内容,calloc分配内存会设置内存中的内容为0,realloc重新调整内存会大小。

引出这个问题的原因是把被替换字符前面通过strncpy复制给tmp之后,通过strcat追加替换字符串会出现追加的点不正确的问题,原因是没有把字符串结尾符'\0'拷贝到字符串结尾。因为malloc的内存不会修改内存中的内容,恰巧内存里面没有'\0'则会造成中间多出来一些无用字符的问题。此问题是在strncpy之后在给字符串加上一个结尾符来解决的,也可以通过calloc或者memcpy申请的内存全部都是'\0'来解决

3.函数内部对形参的修改是否会影响函数外部的内容

形参变量和实参变量是由编译系统分配的两 个不同的内存单元。在函数调用时发生的值传送是把实参变量的值赋予形参变量。

注意上面这句话,如果是普通变量传的直接就是值,如果是指针变量传的是地址。普通变量的话就没什么好说的了,函数内外部没有关联。如果传的是地址的话,内部对地址的修改会反应到外部。但是如果内部对传入地址变量重新附地址后,则对新地址的修改不会影响到外面。

上一篇下一篇

猜你喜欢

热点阅读