c語言實現(xiàn)字符串替換

網(wǎng)上搜了一把,發(fā)現(xiàn)搜到的字符串替換方法都是把字符串的長度寫死的,這樣的話對長字符串替換就存在問題。所以今天就搞一個沒有長度限制的字符串替換方法。

c語言小白,總結(jié)過程中遇到的問題,以點帶面,大神請見諒。

首先總結(jié)一下問題點和知識點

1.字符串和字符數(shù)組的區(qū)別

2.malloc分配內(nèi)存會不會修改內(nèi)存中的內(nèi)容

3.函數(shù)內(nèi)部對形參的修改是否會影響函數(shù)外部的內(nèi)容

接下來貼代碼:

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中第一個出現(xiàn)findchar

????{

????????char *tmp = (char *)malloc(strlen(src) + (strlen(repchar) - strlen(findchar)) + 1);//申請一個新的內(nèi)存可以放下替換后的字符串

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

????????strncpy(tmp, src, findlen - src);//把替換字符前面的拷貝

? ? ? ? tmp[findlen - src] = '\0';//賦值一個結(jié)尾符,下面會說原因

????????strcat(tmp, repchar);//追加替換的內(nèi)容

????????strcat(tmp, findlen + strlen(findchar));//追加之后要替換內(nèi)容之后的字符串

????????src = strdup(tmp);//臨時地址拷貝給src

????????free(tmp);//釋放臨時變量

????}

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

????//return null;

}

思考

? ? ? ? 這種方式每查找到一次替換都要執(zhí)行兩次的申請內(nèi)存操作,是否影響性能,有沒有好的方法?各位有好的方法歡迎指教。

1.字符串和字符數(shù)組的區(qū)別

字符串和字符數(shù)組是不同的兩個概念。char *str = "abc"和char str[] = {'a','b','c'}是完全不同的。

(1)字符串是以第一個'\0'結(jié)尾的一串字符。

(2)字符數(shù)組是一個固定長度的數(shù)組,數(shù)組里面存放的是字符。

直觀舉個例子,“abc\0db”這個是可以存放到字符數(shù)組里面的。并且取出來也一樣。但是如果放到字符串中的話,取出來就是“adc”了。因為字符串檢測到'\0'就認為字符串結(jié)束了。

【注】

char *str = "abc" 中變量str存放在棧中,而變量str指向的內(nèi)容存放在數(shù)據(jù)段中,因為"abc"是數(shù)據(jù)段中的字符串常量,是只讀的不可以修改,所以執(zhí)行str[0]='b'會報錯。str實際長度是4,在abc后面還有一個'\0'。sizeof(str)是4,strlen(str)是3。

char str[]={"abc"}。雖然是字符數(shù)組但是他的長度(sizeof)實際是4,因為“abc”是一個字符串,字符串后面是有'\0'的。但是strlen(str)得到的結(jié)果還是3的。

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

有兩個知識點。一個是字符串和字符數(shù)組的(上面知識點),另一個是內(nèi)存劃分的。

可執(zhí)行程序在內(nèi)存運行時由棧、堆、數(shù)據(jù)段、代碼段組成。

棧:由編譯器自動生成和釋放,存放的是函數(shù)的參數(shù)值,局部變量等

堆:有代碼生成和釋放,一定要釋放,否則內(nèi)存泄漏。通過malloc等方式生成內(nèi)存

數(shù)據(jù)段:分為只讀的,已初始化讀寫的。未初始化讀寫的。只讀的是一些常量,const修飾的。已初始化讀寫的是初始化的全局變量或者靜態(tài)變量。未初始化讀寫的是未初始化的全局變量或靜態(tài)變量。

代碼段:是二進制代碼的存儲區(qū)。

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

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

2.malloc分配內(nèi)存會不會修改內(nèi)存中的內(nèi)容

malloc分配內(nèi)存會不會修改內(nèi)存中的內(nèi)容,calloc分配內(nèi)存會設置內(nèi)存中的內(nèi)容為0,realloc重新調(diào)整內(nèi)存會大小。

引出這個問題的原因是把被替換字符前面通過strncpy復制給tmp之后,通過strcat追加替換字符串會出現(xiàn)追加的點不正確的問題,原因是沒有把字符串結(jié)尾符'\0'拷貝到字符串結(jié)尾。因為malloc的內(nèi)存不會修改內(nèi)存中的內(nèi)容,恰巧內(nèi)存里面沒有'\0'則會造成中間多出來一些無用字符的問題。此問題是在strncpy之后在給字符串加上一個結(jié)尾符來解決的,也可以通過calloc或者memcpy申請的內(nèi)存全部都是'\0'來解決

3.函數(shù)內(nèi)部對形參的修改是否會影響函數(shù)外部的內(nèi)容

形參變量和實參變量是由編譯系統(tǒng)分配的兩 個不同的內(nèi)存單元。在函數(shù)調(diào)用時發(fā)生的值傳送是把實參變量的值賦予形參變量。

注意上面這句話,如果是普通變量傳的直接就是值,如果是指針變量傳的是地址。普通變量的話就沒什么好說的了,函數(shù)內(nèi)外部沒有關(guān)聯(lián)。如果傳的是地址的話,內(nèi)部對地址的修改會反應到外部。但是如果內(nèi)部對傳入地址變量重新附地址后,則對新地址的修改不會影響到外面。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容