C++常见字符串操作函数的实现(strcpy/strcat/strcmp/strlen/strchr/strstr/strpbrk/strrev等)

先看一下字符串操作函数,点这里C语言字符串操作总结大全(超详细)


1、strcpy

函数原型:char *strcpy(char *dest, const char *src) 

函数功能:将源字符串src的内容复制到目的字符串dest中,并返回指向目的字符串dest的指针。

注意:要求dest字符串长度要大于或等于src长度,否则会越界。复制时会将src的结束符'\0'也复制到dest中。

测试:

int main(){
    char s1[]="1234567";
    char s2[]="abcd";
    cout<<strcpy(s1,s2)<<endl<<s1[6];
}
//输出如下
abcd
7

这说明了s2的结束符也复制到s1中了。复制之后s1中变为 a b c d \0 6 7 \0

函数实现:

char *mystrcpy(char *dest, const char *src){
    assert(dest!=NULL && src!=NULL);
    char *destCopy=dest;
    while((*dest++=*src++)!='\0'); //此处已经将src的结束符复制到了dest中
    return destCopy;
}
assert宏,其用法是"assert(表达式)",当表达式为假时强行中止程序,并给出错误提示。需要头文件#include <cassert>

while这一行程序也可以这么写:

while(*src!='\0'){ //相当于while(*src)
    *dest++=*src++;
}
*dest='\0'; //在目标字符串结尾加结束符


2、strncpy

函数原型:char *mystrncpy(char *dest, const char *src, int count)

函数功能:将源字符串src的前count个字符复制到dest中

注意:src的前count个字符将会覆盖dest的相应字符。src的结束符可能被复制进去,这点见下面测试。

测试1:

int main(){
    char s1[]="12345678";
    char s2[]="abcd";
    cout<<strncpy(s1,s2,4)<<endl;
}
//输出如下
abcd5678
测试2:

int main(){
    char s1[]="12345678";
    char s2[]="abcd";
    cout<<strncpy(s1,s2,5)<<endl;
}
//输出如下
abcd
测试1和测试2的区别就是是否把s2的结束符复制到s1中了。

函数实现:

char *mystrncpy(char *dest, const char *src, int count){
    assert(dest!=NULL && src!=NULL);
    char *destCopy=dest;
    while(count--&&(*dest++=*src++)!='\0');
    return destCopy;
}


3、strcat和strncat

strcat函数实现:

char *mystrcat(char *dest, const char *src){
    assert(dest!=NULL && src!=NULL);
    char *destCopy=dest;
    while(*dest!='\0')
        dest++;
    while((*dest++=*src++)!='\0');
    return destCopy;
}
strncat函数实现:

char *mystrncat(char *dest, const char *src,int count){
    assert(dest!=NULL && src!=NULL);
    char *destCopy=dest;
    while(*dest!='\0')
        dest++;
    while(count--&&(*dest++=*src++)!='\0');
    return destCopy;
}

4、strcmp和strncmp

strcmp函数实现:

int mystrcmp(const char *firstStr, const char *secondStr){
    assert(firstStr!=NULL && secondStr!=NULL);
    while(*firstStr&&*secondStr&&*firstStr==*secondStr){
        firstStr++; //只有两字符相等时才往后挪
        secondStr++;
    }
    return (*firstStr-*secondStr);
}

上面程序中while循环如果写成while(*firstStr&&*secondStr&&*firstStr++==*secondStr++)是错的。因为这样的话碰到不相等的字符也往后挪了一位再进行下面的return比较。


strncmp函数实现:

int mystrncmp(const char *firstStr, const char *secondStr, int count){
    assert(firstStr!=NULL && secondStr!=NULL);
    while(count--&&*firstStr&&*secondStr){
        if(*firstStr!=*secondStr)
            return (*firstStr-*secondStr);
        else {
            firstStr++;
            secondStr++;
        }
    }
    return 0;
}
在网上看到有人把strncmp函数这样写:

int strncmp(const char *s, const char *t, int count)
{
    assert((s != NULL) && (t != NULL));
    while (*s && *t && *s == *t && count --)
    {
        ++ s;
        ++ t;
    }
    return (*s - *t);
}
这么写是错的,比方说strncmp("12345678","1234abcd",4); 本来输出应该是0,但是下面的这种写法输出是-44,因为他比较的是第五位'5'和'a'  注意这点小细节。

5、strlen

int mystrlen(const char *str){
    int count=0;
    while(*str!='\0'){
        str++;
        count++;
    }
    return count;
}

6、strchr

测试:

char s1[100]="12345678";
cout<<strchr(s1,'4')<<endl;
//output
45678
返回的是指向所给字符的指针


strchr函数实现:

char *mystrchr(char *str, int c){
    assert(str!=NULL);
    while(*str++!='\0'){
        if(*str==(char)c)
            return str;
    }
    return NULL;
}

7、strstr

测试:

char s1[100]="12345678";
char s2[]="56";
cout<<strstr(s1,s2)<<endl;
//output
5678
strstr函数实现:

char *mystrstr(char *str1, const char *str2){
    int len=strlen(str2);
    while(*str1!='\0'){
        if(strncmp(str1,str2,len)==0)
            return str1;
        str1++;
    }
    return NULL;
}
另外一种实现方式:

char *mystrstr(char *str1, char *str2){
    while(*str1!='\0'){
        char *s1=str1,*s1Copy=str1;
        char *s2=str2;
        while(*s1&&*s2&&*s1==*s2){
            s1++;
            s2++;
        }
        if(*s2=='\0')
            return s1Copy;
        str1++;
    }
    return NULL;
}

8、strpbrk

函数功能见如下测试。

测试:

char s1[100]="12345678";
char s2[]="002001";
cout<<strpbrk(s1,s2)<<endl;
//output
12345678

char s1[100]="12345678";
char s2[]="00200";
cout<<strpbrk(s1,s2)<<endl;
//output
2345678


strpbrk函数实现:

char *mystrpbrk(char *str1, char *str2){
    while(*str1!='\0'){
        if(strchr(str2,*str1)!=NULL)
            return str1;
        str1++;
    }
    return NULL;
}


9、strrev

功能:翻转字符串

strrev函数实现1:

char *mystrrev(char *str){
    int len=strlen(str);
    reverse(str,str+len); //需要 #include<algorithm>头文件
    return str;
}
strrev函数实现2:

char *mystrrev(char *str){
    int len=strlen(str);
    for(int i=0;i<len/2;i++){
        swap(str[i],str[len-1-i]);
    }
    return str;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值