编译c语言时时找错误,今天作C语言程序的时候偶有心得,发现自己过去的很多程序是错误的.愿与各位共享....

这篇博客讨论了一个C语言函数`replacestr()`,用于在源字符串中替换指定子串。作者提供了不同的实现方案,包括使用`strstr()`、`memmove()`等函数,并探讨了内存管理和函数设计的注意事项。博客中还包含了其他网友的评论和建议,如函数优化、内存分配责任和错误处理。
摘要由CSDN通过智能技术生成

请各位不要解释为什么这样写的原因都写一个函数,要求如下

char *replacestr(char* source_str,char* repl_str, char* with_str)

{

}

这个函数要求在source_str中用with_str替换repl_atr.大家看看是否简单,但是这个函数真的非常见功底.大家不妨尝试.

|

{

char *p, *buf;

if (!(p=strstr(source_str, repl_str)))

return(NULL);

buf=(char *)calloc(strlen(source_str)-strlen(repl_str)+strlen(with_str)+1, sizeof(char));

memmove(buf, source_str, p-source_str);

memmove(buf+(p-source_str), with_str, strlen(with_str));

memmove(buf+(p-source_str)+strlen(with_str), p+strlen(repl_str), strlen(p)-strlen(with_str));

return(buf);

}

|

strstr()就是这么做的,它不分配内存,只是在原串中查找。

如果结果不是"???????",我到会觉得很可怕

|

呵呵,当时我是想到这个问题了。

与其在这个函数里面进行多次替换,不如再写个wrapper函数。所以当时没写。

下面是完整的程序:

strrep是strrep0的wrapper。

strrep0只替代第一个出现的,

strrep调用strrep0迭代替换。

#include

char *strrep0(char* source_str,char* repl_str, char* with_str)

{

char *p, *buf;

if (!(p=strstr(source_str, repl_str)))

return(NULL);

buf=(char *)calloc(strlen(source_str)-strlen(repl_str)+strlen(with_str)+1, sizeof(char));

memmove(buf, source_str, p-source_str);

memmove(buf+(p-source_str), with_str, strlen(with_str));

memmove(buf+(p-source_str)+strlen(with_str), p+strlen(repl_str), strlen(p)-strlen(repl_str));

return(buf);

}

char *strrep(char* source_str,char* repl_str, char* with_str)

{

char *p, *q;

p=strdup(source_str);

while((q=fun(p, repl_str, with_str)))

{

free(p);

p=q;

}

return(p);

}

|

学习ing...

|

char *replacestr(char* source_str,char* repl_str, char* with_str)

{

int len,w_len;

char *s,*r,*w,*p;

s = source_str;

r = repl_str;

w = with_str;

w_len = strlen(w);

for(p=s;p!=NULL;)

{

s = strstr(s,w);

if(s==NULL)

{

strcpy(r,p);

break;

}

len = s - p;

memcpy(r,s,len);

s += len;

r += len;

memcpy(r,w,w_len);

r += w_len;

}

return repl_str;

}

|

你的程序十有八就会core.

|

兄弟,你这个不就是要两个异常判断就搞定了吗?

1。 判断空指针和空字符串

2。 判断是否存在内存覆盖

|

char *replacestr(char* source_str,char* repl_str, char* with_str)

{

int len,w_len,r_len;

char *s,*r,*w,*p,*q,*t;

s = source_str;

r = repl_str;

w = with_str;

w_len = strlen(w);

r_len = strlen(r);

t = (char*)malloc(strlen(s)+w_len-r_len+1);

for(p=t,q=s;;)

{

q = strstr(s,r);

if(q==NULL)

{

strcpy(p,s);

break;

}

len = q - s;

memcpy(p,s,len);

p += len;

memcpy(p,w,w_len);

p += w_len;

s += len + r_len;

}

strcpy(source_str,t);

free(t);

return source_str;

}

|

还是会core的。

你怎么保证替换后的字符串比原串短?

|

我知道有这个问题,如果真的要解决的话,最好的办法是再加2个参数,

char *replacestr(char* source_str,char* repl_str, char* with_str,char *out_buf,int len);

|

在使用频率较高,功能单一的函数中最好不要加入过多的有效性检查,要放在较高一层去做

|

如果注意一下,调用函数的原型,错误会少多了

strstr(..) 函数返回值是 char* 指针,即所匹配的地址,库函数里很少会主动帮调用者申请空间的.(涉及到 释放等原因),若有,函数帮助中回特别说明

|

子函数负责分配空间,父函数负责释放。这是很常用的做法。

特别是父函数该分配多时时经常使用。

库函数也有,比如strdup()。

如果你经常读代码,应该会常看到这种情况。

|

Sorry,笔误。

“特别是父函数不知道该分配多时时经常使用。”

|

我觉得子函数负责分配空间,父函数负责释放,只是不得以的做法。好的做法是分配与释放内存都在同一个层次进行,要么是在同一个函数内,要么设计2个单独的函数,一个分配了内存,另一个负责释放

|

我不认为是不得以的办法。

你可以man一下getcwd,getcwd函数的参数已经有指针了,

但如果该参数为NULL,getcwd会为你分配堆空间的。

你一可以考虑calloc,它实际上是一个malloc加一个memset

实际上完全可以将他们分开,但为了方便定义了calloc

再比如c++中的new运算符,实际上是malloc后调用构造函数。

在逻辑上,你可以把任何子函数分配空间的函数看成内存分配函数。

他们在逻辑上跟malloc没什么区别,只不过又作了一点其他处理,

就象calloc一样,只不过可能比calloc复杂一点。

|

若调用者忘记释放空间,就会有内存泄漏,若释放方式不对,如 malloc ->用了 delete,

new 来的用 free,

另外 对于楼主的问题

用转成 std::string 更简单

string::substr(..),

string::replace(...)

|

说来说去,只是编程的风格不同,但有一点一定对的,没把握的话,最好man函数帮助.从某个侧面上说,对开发者来说,文档资料是如此的重要,

没人会知道你提供的库,是否有无心的"陷阱"

|

good

|

忘了释放空间或这释放错了,这跟到底是谁分配的内存无关。

而是写程序的人的错误。如果这个人无法认真的阅读理解C程

序中关于内存分配的问题。那我建议他还是用象Java这样带GC

功能的语言吧,只是别指望用这类语言进行系统程序设计。

打个比方:

假设你自行车骑不好而经常摔交,那时你的问题,不是自行车的问题。

也别说是自行车给你设下的陷阱。如果你骑不好非想骑而又不想摔交,

可以买个儿童自行车,就是后轮带两边各带一个小轮的那种。或干脆

改骑三轮吧。

|

用shell比C++还简单,一行搞定:

echo $source_str | sed "s/$replace_str/$with_str/g"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值