字符串函数-具体实现

 

 

1、strcpy(s1,s2);复制s2到s1中;

char *my_strcpy(char *dst,const char *src)
{
	assert(dst != NULL);
	assert(src != NULL);
	char *ret = dst;
	while((* dst++ = * src++) != '\0') 
		;
	return ret;
}

上述的while执行过程:

  • the contents of t (*dst) are copied to s (*src), one character.
  • src and dst are both incremented (++).
  • the assignment (copy) returns the character that was copied (to the while).
  • the while continues until that character is zero (end of string in C).

需要注意的是:

 strcpy 会拷贝'\0',还有要注意:[4]

  • 源指针所指的字符串内容是不能修改的,因此应该声明为 const 类型。

  • 要判断源指针和目的指针为空的情况,思维要严谨,这里使用assert

  • 要用一个临时变量保存目的串的首地址,最后返回这个首地址。

  • 函数返回 char* 的目的是为了支持链式表达式,即strcpy可以作为其他函数的实参。

等价于如下的代码:

while (*t) {
    *s = *t;
    s++;
    t++;
}
*s = *t;

在C++中正确运行的效果:

#include <iostream>
using namespace std;

//#include<stdio.h>
#include<assert.h>
#define N 50


char *my_strcpy(char *dest, const char *src)
{
//返回值保存
char *p = dest;//检查入参,使程序健壮
assert(dest != NULL || src != NULL);//注意越界
while ((*dest++ = *src++) != '\0');
return p;              //返回字符指针,使函数可以用于链式表达式,增强可用性
}
int main()
{
char str1[N];
char *str2 = "Everything  is    well.";
printf("%s\n", my_strcpy(str1, str2));
printf("%s\n", str1);
printf("%s\n", str2);
//system("pause");
//return 0;
}

运行结果:

Everything  is    well.
Everything  is    well.
Everything  is    well.

参考:

[1]https://blog.csdn.net/u014744118/article/details/48996653

[2] https://blog.csdn.net/Gpengtao/article/details/7464061

[3] https://stackoverflow.com/questions/810129/how-does-whiles-t-copy-a-string

[4] https://blog.csdn.net/lisonglisonglisong/article/details/44278013

2、strcat(s1,s2)

连接字符串s2到字符串s1的末尾

#include <assert.h>
#include <stdio.h>
 
char* strcat(char* des, const char* src)   // const表明为输入参数 
{  
	assert((des!=NULL) && (src!=NULL));
	char* address = des;
	while(*des != '\0')  // 移动到字符串末尾
		++des;
	while(*des++ = *src++)
		;
	return address;
}

需要注意的是:des 和 src 所指内存区域不可以重叠且 des 必须有足够的空间来容纳 src 的字符串

在C++中运行的结果:

#include <iostream>
using namespace std;

#include <assert.h>
#include <stdio.h>
#define N 50
char* mystrcat(char* des, const char* src)   // const表明为输入参数 
{  
	assert((des!=NULL) && (src!=NULL));
	char* address = des;
	while(*des != '\0')  // 移动到字符串末尾
		++des;
	while(*des++ = *src++)
		;
	return address;
}

int main()
{
char str1[N]="hh";//注意这里改为指针出错
char *str2 = "Everything  is    well.";
printf("%s\n", mystrcat(str1, str2));
printf("%s\n", str1);
printf("%s\n", str2);
//system("pause");
//return 0;
}

结果:

hhEverything  is    well.
hhEverything  is    well.
Everything  is    well.

参考:

[4] https://blog.csdn.net/lisonglisonglisong/article/details/44278013

3、strlen(s1) 

返回字符串s1的长度

#include <assert.h>
#include <stdio.h>
 
int strlen(const char* str)
{
	assert(str != NULL);
	int len = 0;
	while((*str++) != '\0')
		++len;
	return len;
}

注意:while循环的过程和第一种情况类似 先*str 然后再执行str++

C++ 中运行的结果:

#include <iostream>
using namespace std;

#include <assert.h>
#include <stdio.h>

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

int main()
{
char *str2 = "Ever .";
printf("%s\n", str2);
printf("strlen(str1)=%d, sizeof(str1)=%d\n", mystrlen(str2), sizeof(str2));
//system("pause");
//return 0;
}

运行结果:

Ever .
strlen(str1)=6, sizeof(str1)=8

4、strcmp(s1,s2)

s1=s2时 返回0

s1<s2时返回值小于0

s1>s2时返回值大于0

注意它们比较的是:ASCII值大小相比较, 两个字符比较,直到出现不同的字符遇'\0'为止,也就是相等的情况是两个字符串的所有字符全部相等。

int mystrcmp(const char *str1, const char *str2)
{
   int ret=0;
   while( !(ret = *(unsigned char*)str1 - *(unsigned char*)str2 ) && *str1 )
     {
       str1++;
       str2++;
     }
     if(ret < 0)
        return -1;
     else if(ret > 0) 
        return 1;
     return 0;    
 }

C++中的实现:

#include <iostream>
using namespace std;

#include <assert.h>
#include <stdio.h>

 int mystrcmp(const char *str1, const char *str2)
{
   int ret=0;
   while( !(ret = *(unsigned char*)str1 - *(unsigned char*)str2 ) && *str1 )
     {
       str1++;
       str2++;
     }
     if(ret < 0)
        return -1;
     else if(ret > 0) 
        return 1;
     return 0;    
 }


int main()
{
char *str1 = "Ever .";
char *str2 = "Aver .";
  //char	str1[] = "abcdf";
  //char	str2[] = "abcdw";
printf("%s\n", str2);
printf("%d\n",mystrcmp(str1, str2));
//system("pause");
//return 0;
}

运行结果:

Aver .
1
 

【1】https://blog.csdn.net/lina_acm/article/details/51910119 值得参考的博客(写的不错):

5、strchr(s1,ch)

返回一个指针,指向字符ch首次出现在S1中的位置

C++中实现:

char *mystrchr(const char *s,int ch)
{
	assert(s!=NULL);
 
	while(*s!='\0')
	{
		if(*s-ch==0)
			return (char*)s;
		s++;
	}
	return NULL;
}

 需要注意的是:它是指针函数的实现。因为最后要返回地址和strcpy类似(区分前面的)。

#include <iostream>
using namespace std;

#include <assert.h>
#include <stdio.h>

char *mystrchr(const char *s,int ch)
{
	assert(s!=NULL);
 
	while(*s!='\0')
	{
		if(*s-ch==0)
			return (char*)s;
		s++;
	}
	return NULL;
}



int main()
{
char *str1 = "AEer .";
//char str1[] = "AEer .";
char *p ;
p=mystrchr(str1,'e');		
  
	if(p!=NULL)
	{
		cout<<"Findout!"<<endl;
		cout<<p<<endl;
	}
	else
	{
		cout<<"Not Find!"<<endl;
	}


//system("pause");
//return 0;
}

运行结果:

Findout!
er .

需要注意的是它返回的是首次出现的字符及后面的字符串。

区分指针函数和函数指针的区别

      int *f(int i, int j);

        int (*p)(int i, int j);

    前者是返回值是指针的函数;后者是一个指向函数的指针。

参考:【1】https://blog.csdn.net/str999_cn/article/details/78591369

6、strstr(s1,s2)

返回一个指针,指向字符串s1中字符串s2出现的位置

类似KMP算法(朴素的)

char *mystrstr(const char *s1, const char *s2)   
{  
    int n;  
    if (*s2)   
    {   
        while (*s1)   
        {   
            for (n = 0; *(s1 + n) == *(s2 + n); n ++)  
            {   
                if (!*(s2 + n + 1))   
                    return (char *)s1;   
            }   
            s1++;   
        }  
        return NULL;   
    }   
    else   
        return (char *)s1;   
} 

C++中运行的实例:

#include <iostream>
using namespace std;

#include <assert.h>
#include <stdio.h>

char *mystrstr(const char *s1, const char *s2)   
{  
    int n;  
    if (*s2)   
    {   
        while (*s1)   
        {   
            for (n = 0; *(s1 + n) == *(s2 + n); n ++)  
            {   
                if (!*(s2 + n + 1))   
                    return (char *)s1;   
            }   
            s1++;   
        }  
        return NULL;   
    }   
    else   
        return (char *)s1;   
} 



int main()
{
char str1[] = "Abcabdabc .";
char str2[] = "abc";
//char *str1 = "Abcabdabc .";//可以为指针形式
//char *str2= "abc";
char *p ;
p=mystrstr(str1,str2);   
  
	if(p!=NULL)
	{
		cout<<"Findout!"<<endl;
		cout<<p<<endl;
	}
	else
	{
		cout<<"Not Find!"<<endl;
	}


//system("pause");
//return 0;
}

运行 结果:

Findout!
abc .
注意的是选择指针的方式赋值字符串出错(类似第一种情况strcat)原因是? 注释没加好导致

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

heda3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值