字符串中常见函数的实现_legend



字符串操作函数的自我实现:
(1)strcpy(),strncpy()的实现:
(2)strcat(),strncat()的实现:
(3)strstr()的实现:
(4)memcpy()的实现:
(5)memset()的实现:
(6)strcmp()的实现,strncmp()的实现:
(7)strstr()的实现:
(8)strlen()的实现:
-------------------------------
(1)strcpy()的实现:
函数原型是 char *strcpy(char *strDest,const char *strSrc);,其中strDest是目的字符串,strSrc是源字符串。

实现:
char *strcpy(char *strDest,const char *strSrc)
{
    assert((strDest!=NULL)&&(strSrc!=NULL));
 //assert()中的条件为真时,继续执行,否则退出。

    char *address=strDest;
    while((*strDest++=*strSrc++)!='\0');
 //不需要在末尾添加*strDest='\0',因为结束时,已经='\0';
    return address;
}


/*注意:
1.strncpy中对于dest末尾的'\0'的处理
2.&&的运算顺序问题
*/
char* strncpy(char* dest,const char* src, int count){
 assert(dest!=NULL && src!=NULL);
 char* temp=dest;
 int i=0;

 while(i++< count && (*dest++=*src++)!='\0');

 //注意对于temp的末尾的'\0'的处理
 *temp='\0';

 return temp;
}

注意:刚开始我写strncpy的实现时,把while(i++ < len && (*temp++ = *src++)!='\0')写成了while( (*temp++ = *src++)!='\0' && i++ < len); 导致最后多复制了一个字符。  因为&&运算顺序的问题,只要&&的左边为假,则整体为假,右边不再执行。

------

(2)memcpy:内存拷贝函数;
1)说明:
void *memcpy(const void *dest, const void *src, size_t n);
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。

2)说明:
1.注意目的地址和源地址重合的问题,拷贝前要加以判断。
2.一般要把原来的指针类型转换成char*,这样每次移动都是一个字节。
3.memcpy是一次复制一个字节,不一定是字符串,所以不需要在结尾加上'\0';
3)实现:

void * memcpy(const void * dest,  const void * src, int len){
 
 int i=0;
 const char* tempdest=(char*)dest;
 const char* tempsrc=(char*) src;

 assert(tempdest!=NULL && tempsrc!=NULL);

 //tempdest在tempsrc到tempsrc+len-1之间,
 //如果从头到尾赋值,则*tempsrc赋值给*tempdest,会发生覆盖,
 //所以从后往前开始赋值。

 if(tempdest>=tempsrc && tempdest<=(tempsrc+len-1) ){
  tempdest+=len;
  tempsrc+=len;
  i=len;

  while(i>0){
   *tempdest-- = *tempsrc--;
   i--;
  }

 }else{
  while(i<len){
   *tempdest++ = *tempsrc++;
   i++;
  }
  
 }

 return dest;
}
  
  

3)memcpy与strcpy的区别:

1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy

------

(3)strcat();

 char * strcat(char * dest ,const char* src){
  char * tmp=dest;
  while(*dest)//定位到dest的'\0'位置处,从这个位置开始追加。
  dest++;

  while((*dest++=*src++)!='\0');

  return tmp;
 }


/*
注意:1.strncat结尾处'\0'的处理;
2.&&的运算顺序问题;
*/

 char * strncat(char * dest ,const char* src, int n){
   char *tmp=dest;//保存dest的初始值

   assert(dest!=NULL && src!=NULL);

   while(*dest !='\0')
   dest++;

   while(n-- && (*dest++ = *src++ )!='\0' );

   
   *dest='\0';

   return tmp;
   
 }

注意:如果将n-- && (*dest++ = *src++ )!='\0'写为
(*dest++ = *src++ )!='\0' && n--,则会多复制一个元素。


 -------

 (3)memset的实现:
 1)函数头:
 void * memset(void * dest ,int c ,int len);
 2)功能:
 将dest所指地址开始的len个字节的内容全部置位为ch所指的ASCII的值。
 3)实现:

 void memset(void * dest ,int c ,int len){
  char * temp=(char *)dest;

  assert(temp!=NULL);

  while(len-->0){
   *temp**=(char) c;
  }

  return dest;
 }


 -------
(6)strcmp()的实现:

/*如果dest > source,则返回值大于0,如果dest = source,则返回值等于0,如果dest  < source ,则返回值小于0。*/ 
 
int strcmp(const char* dest ,const char * src){
 
 int ret=0;

 while( (ret=*(unsigned char *)dest -*(unsigned char *)src )==0  && *dest ){
  dest++;
  src++;
 }

 if(ret<0) return -1;
 else if(ret>0) return 1;
 return 0;
}

 

注意:&&的运算顺序,此中ret=*dest-*src 在 *dest前面。

-------
(6-1)strncmp()的实现:

1)原型:
int strncmp(const char* s1,const char* s2, int n);

2)功能:
比较s1的前n个字符和s2的前n个字符;

3)实现:

int strncmp(const char* s1, const char * s2,int n){
 assert(NULL != s1 && NULL !=s2);

 while(n--){

  if(*s1 && *s1==*s2){
   s1++;
   s2++;
  }
  else {
   return *s1-*s2;
  }
 }

 return 0;//如果前n个字符都相等
}

-------
(7)strstr()的实现:
1)原型:
char * strstr(const char* s1,const char* s2);

2)功能:
在s1中找到s2第一次出现的位置,返回该位置,如果没找到,则返回NULL.

3)实现:

/*

基本思想就是:

对于字符串s1,从左到右,不断的选择选择新的字符作为起点,看s2是否和新起点开始的的字符串的前n个字符相同;

n为s2字符串的长度;

*/

char * strstr(const char* s1, const char* s2){
 int len2;

 if( ( len2=strlen(s2) )==0 )
 return (char*)s1;

 for(;*s1;s1++){
  if(*s1==*s2  && strncmp(s1,s2,len2)==0 )
  return (char*) s1;
 }

 return NULL;
}

方法二:

const char* Strstr(const char * str1, const char * str2) {
    assert(str1);
    assert(str2);
    char* cp = (char*)str1;
    char* substr = (char*)str2;
    char* s1 = NULL;
    if (*str1 == '\0')
        return NULL;
    while (*cp) {
        s1 = cp;
        substr = str2;
        while (*s1 && *substr && (*s1 == *substr)) {
            s1++;
            substr++;
        }
        if (*substr == '\0')
            return cp;
        cp++;
    }
}
 

----------------
(8)strlen()的实现:

1)原型:
int strlen(const char* str);

2)实现:
方法一:

int strlen(const char * str){
 assert(str!=NULL);

 int len=0;

 while((*str++)!='\0')
 len++;

 return len;
}

方法二:
int strlen(const char* str){
 assert(str);

 const char* temp=str;

 while(*temp ++);//循环结束*temp=='\0'

 return temp-str-1;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值