当前位置:  技术问答>linux和unix

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

    来源: 互联网  发布时间:2015-02-10

    本文导语:  请各位不要解释为什么这样写的原因都写一个函数,要求如下 char *replacestr(char* source_str,char* repl_str, char* with_str) { } 这个函数要求在source_str中用with_str替换repl_atr.大家看看是否简单,但是这个函数真的非常见功底.大家不妨尝...


请各位不要解释为什么这样写的原因都写一个函数,要求如下
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"

    
 
 

您可能感兴趣的文章:

  • c语言判断某一年是否为闰年的各种实现程序代码
  • 有人用过centos吗?请问在centos下怎么在终端运行C语言程序或者JAVA程序?
  • c语言基于libpcap实现一个抓包程序过程
  • C语言程序库 LibU
  • 据说这是史上最变态的6个C语言Hello, World程序
  • 请问如何在C语言中嵌入的shell脚本中获得C语言程序中定义的某个变量
  • linux 桌面应用程序和web应用程序编写常用的语言
  • 如何使用yacc分析c语言程序?
  • linux下,简单c语言程序
  • 在SCO OpenSever 5中如何编译C语言程序???
  • 有关Linux下用eclipse写C++语言程序的编译问题
  • 请问SCO UNIX下如何编译C语言程序
  • 在Linux下,如何将输出到屏幕的数据赋值给一个C语言程序里的变量
  • 后台C语言程序(搜索引擎模块) 如何和前台页面交互???
  • c语言实现程序互斥问题 急.....
  • (基础)linux下c语言程序的编译问题
  • 在Linux上用C语言作了一个程序,程序中申请(malloc)了很大的内存,但是没free,当程序运行结束后,内存是否自动释放?
  • 程序设计语言 Objeck
  • 关于Linux下C语言程序的交互式进程管理
  • 急!!在线等!! C语言程序操作mysql怎样在Linux上运行!!立刻揭贴!!
  • 我需要做一个红帽下的串行口C语言通讯程序程序谁能帮我一下
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • linux 下的如何编辑调试C语言程序,有无可视化开发环境
  • C语言程序提示段错误
  • 在线等:我要怎么才能运行刚写的C语言程序并看到它的结果?
  • 如何将C语言代码转换为应用程序(也就是编译)
  • 敬请关注;关于系统进程的c 语言程序
  • Linux 中用java语言写串口程序,提示找不到串口
  • 请问unix终端的光条式菜单程序是用什么语言开发的?谢谢
  • linux下用c语言写的程序,其中可以使用STL模板吗?先谢谢各位
  • 如何在我的C语言编写的程序里面执行命令行命令,比如ls -la ??
  • 求一个在Linux下运行的C语言小程序.
  • 通过libsqlora8-2.2.10--c语言程序连接oracle数据库,需要连接,查询,修改等,急!!!
  • 谁能帮我用C语言编一个在LINUX下播放WAV文件的程序
  • Linux下C语言程序中怎么发送邮件???
  • 请教:想用c语言编写能使浏览器启动的一个程序?
  • linux C语言 获取当前程序运行时路径
  • 关于Linux下C语言程序的交互式进程管理 iis7站长之家
  • 菜鸟问题——其他语言怎样使用Java编写的程序(明确地说,使Class)
  • 100分求linux下c语言的路由器程序
  • 那有Richard Blum 马朝辉译的《汇编语言程序设计〉的电子版下载
  • C语言中什么函数可以设置程序的当前工作路径


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3