C语言字符串操作

重点是掌握算法,对字符串的存储、操作深入理解,能编程实现和灵活运用,即达到目的。不断扩充...

(一)、子串查找函数  findsub,findSubNum

1-1、查找子串

/*
函数名: findsub
函数原型:const char * findsub(const char * base, const char* sub);
功能:从字符串base中查找是否有字符串sub,如果有,从base中的有sub位置起,返回base在该处的指针,如果没有,返回null。
返回值:返回该位置的指针,如找不到,返回空指针。

思路:对base串的每个字符,依次作为起点和sub字串的逐个匹配,若sub串匹配完毕,则找到,返回base在该处的指针。否则,继续以base的下一个字符为起点,至base串的最后一个字符时仍无匹配,返回NULL。  (匹配,通过监测sub的所有字符是否等于base的某个子序列,通过‘\0’实现)
*/

const char * findSub(const char * base, const char *sub)
{
    if((base==NULL)||(sub==NULL))
        returnbase;
 
    while(*base)                      //while(!base)
    {
        constchar *b = base;
        constchar *s = sub;
        while(*b++== *s++)
        {
            if(!*s)                  //if(!s)
                returnbase;
        }
        base=base+1;
    }
 
    return NULL;
}
int main()
{
char base[10] = "chinese";
char sub1[3] = "ne";
char sub2[6] = "tommy";
 
cout<<findsub(base,sub1)<<endl;
// cout<<findsub(base,sub2)<<endl;  出现运行时错误!cout<<(char *)NULL;
return 0;}

@@小插曲:bug

检查了findsub函数本身无错误,但是main函数出现运行时错误,判断应该是查找不到"子串"时返回NULL的问题。
经测试,发现问题是char *类型指针为NULL时引发的
由于操作符<<重载,当指针pc是char *型时,<<pc实际上是输出pc指向的内容即*pc。
而本程序中,cout<<findsub(base,sub2)<<endl;编译器会新建临时char *指针,当findsub返回NULL时,该指针为0,试图读数据时,系统认为访问非法。
而当pc为 
int *类型的NULL指针时,<<pc不是读内容,则输出pc内存地址;

进行了以下测试:
1)在程序中语句cout<<NULL;是可以的,相当于cout<<0;   18817597901
2)cout<<(int*)(find(base,sub2))<<endl;也是可以的。0
修改了main程序:

int main()
{
        char base[10] = "chinese";
        char sub1[3] = "ne";
        charsub2[6] = "tommy";
 
        if(findsub(base,sub1))
            cout<<findsub(base,sub1)<<endl;
        else
            cout<<"not found!"<<endl;
 
       if(findsub(base,sub2))
             cout<<findsub(base,sub2)<<endl;
       else
             cout<<"not found!"<<endl;
       return 0;
}

1-2、变种函数findSubNum:编写函数检查主串中字串出现的次数

/*
函数名: findSubNum
函数原型:int findsub(const char * src, const char *sub);
功能:检查并输出在字串sub在字符串src中出现的次数。
返回值:出现个数。

思路对base串的每个字符,依次作为起点和sub字串的逐个匹配,若sub串匹配完毕,则找到一个。继续以base的下一个字符为起点,最后统计次数。  (注意如何编程实现匹配的代码段 )
*/

int findSubNum(const char *src, const char *sub)
{
    int count =0;
    const char *p ;
    const char *m ;
   
    while(*src)         //遍历src串
    { 
        p = src;           //
        m = sub;           //每次匹配查找前,先check指针p,m的值 !!
        while(*p++ == *m++)  //以p为起点,和子串逐个比较。如果比较完成*m='\0',则存在
        {
            if(*m=='\0')                 // bug:写成了= error C2166: l-value specifiesconst object
                {count++;  break;}
        } 
        src++; 
    }  
 
    return count;
}


(二)、字符串逆置函数

2-1  将字符串逆置 strReverse

原型:char *strReverse(char *base);

功能:把字符串base的所有字符的顺序颠倒过来(不包括空字符NULL)。

说明:返回指向颠倒顺序后的字符串指针

char * strRerverse(char * base)
{
       if(base==NULL)  return NULL;       // or
       char *top= base;                   //base内容赋值给p;
       char *end=base+strlen(base)-1;    //指向字符串尾地址
       chartemp;
 
     while(top++< end--)
    {
       temp =*top;
       *top =*end;
       *end =temp;   // 交换
    }
    return base;
}

2-2  将字符串的所有单词逆置,单词内部结构不变strReverseByword

原型:char * strReverseByword(char *src)

功能:将字符串src中单词的位置逆置,不改变单词的内部结构!

说明:返回首地址指针

思路:首先将每个单词逆置,最后字符串整体逆置。每个字符逆置2次,以单词为单位的角度看逆置一次。注意编程时的控制结构。

/* 将字符串中的单词顺序逆置,单词内部结构不变 */

char * strReverseByword(char *src)
{
    char *start =src;
    char *end =src;
    char *p =src;
 
 
    while((*p++)!='\0')     //遍历字符串src
    {
        if((*p=='')||(*p=='\0'))    //如果p指向单词尾部或字符串尾部;
        {
            end =p-1;             //单词尾部
            while(start<end)
                swap(*start++,*end--);
 
            start= p+1;           //下一个单词首部 (每次调整首尾指针)
        }
    }      //注意:跳出while循环时p指向'\0'后的第2单元
    start = src,end =p-2;
    while(start<end)
    {
        swap(*start++,*end--);
    }
    return src;
}
 
//  "i amfrom shanghai"
 
int main()
{
    char pt[20]= "i am from shanghai!";
   cout<<"string is :"<<pt;
   cout<<"\nAfter reversed: "<<strReverseByword(pt);
    /*  ERROR:字符常量不能写,存放在字符常量区。
    char * ptr ="i am from shanghai!";
   cout<<"\nAfter reversed: "<<strReverseByword(ptr);
    */
    return 0;
}

(三)比较函数 strcmp

/*

原型:int strcmp(const char *s1,const char * s2);

功能:比较字符串s1s2

返回值:当s1<s2时,返回值<0

s1==s2时,返回值=0

s1>s2时,返回值>0

*/

int strcmp(const char *src, const char *dest)

{
         const char *p = src;
         const char *t = dest;        
         assert((src==NULL)&&(dest==NULL));

         while(*p == *t)
         {
              if((*p=='\0')&&(*t=='\0'))
                        return 0;
                    p++;
                    t++;
         }
         if(*p>*t)   return 1;
         else    return -1;
}


 

 

 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值