[C] 一个字符串处理的问题

今天有人问起,这样一个问题:

char   a[]="peter@163.com.cn   jack@163.com.cn   tom@163.com.cn";

怎么才能够把a[]中的".cn"去掉?
===============================================================
这是一个C语言的字符串处理,如果硬来的话一个一个的匹配然后替换,很容易实现。
但是要考虑实现简单而高效还是要动动脑筋的。我当时思考的思路是,逐个找到。cn的位置
(strstr),然后截取字符串区域拷贝(memcpy),程序如下:

  
  
int  main()
{
    
char * tail=NULL;
    
char*  front = NULL;
    
char seps[] = ".cn";
    
int c = 0;
    
char str[] = "I'm a student's .com .cn jkkajdklafj  .cn";
    
char *pnewStr = (char*) malloc(strlen(str)+1);
    ::memset(pnewStr, 
0sizeof(char)*(strlen(str)+1));

    tail 
= str;
    front 
= str;
    
while(front = strstr( front, seps ))
    
{
        ::memcpy(pnewStr
+c, tail, (front - tail)*sizeof(char));
        c 
+= (front - tail);
        front 
+= 3;
        tail 
= front;
    }


    ::memcpy(pnewStr
+c, tail, (str+strlen(str)-1)-tail+1);
}




后来有位仁兄发了一个程序,自愧不如啊,在这里我贴出来大家瞧瞧:


#include 
< stdio.h >
/***********************************************************************
 * Function   : char *strrmv3(char *s1, char *s2); 
 * Author     : loops
 * Date       : 2007.11.28
 * Description: Remove sub string s2 from s1 without invoking any other functions.
 *              Maximum copy times: strlen(s1); Maximum scan times: strlen(s1)
 *              Assembly instructions: 49
 **********************************************************************
*/

char *  strrmv3(  char   * s1,  char   * s2)
{
    
char *w=s1, *r=s1, *p;//w: 写入位置,r: 读入位置   p: 用于处理s2
    for( p=s2; *r; *w++=*r++ )
        
!(*p)&&(w-=(p-s2),p=s2), (*r!=*p)?p=s2:p+=1;
    
*? *w='' : *(w-=(p-s2))='';//如果*p=='�',说明s1末尾匹配成功了。
    return s1;
}


int  main()
{
    
char str[]="peter@163.com.cn   jack@163.com.cn   tom@163.com.cn";
    printf(
"%s",strrmv3(str,".cn"));
    
return 0;
}

呵呵,相信大家看了以后都会觉得很难懂,这位loops兄为了压缩代码行数,所以故意写的晦涩了一些,
下面是一个解释版本,这样就清楚多了:


char *  strrmv3(  char   * s1,  char   * s2)
{
    
char *w=s1, *r=s1, *p;//w: 写入位置,r: 读入位置   p: 用于处理s2
    for( p=s2; *r; *w++=*r++ )
   
{
       
if*p=='' )//说明s2匹配成功
       {
          w
-=(p-s2); //写入位置回退s2的长度个字节
          p=s2;      //p重新置为s2的头
       }

       
if*r!=*p ) //如果当前字符与*p不相等
       {
           p
=s2;    //匹配失败,p重新置为s2的头
       }
else
       
{
          
++p;     //当前字符符合*p,p++,继续向前走。
       }

   }

    
//处理s1末尾匹配成功s2的问题,如果*p=='�',说明s1末尾匹配成功了。
    if*p )
    
{
      
*w='';
    }
else
    
{
       w
-=(p-s2);
       
*w=''
    }

    
return s1;
}

呵呵,怎么样,后者的方法明显比我好多了,强烈推荐,我想C库函数也不过是如此了。
好的代码大家一起学习了~~~~~~~~~~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值