Character processing strlen(), strcmp(), strstr() source code and adaptation

int strcmp(const char* str1,const char *str2)

The strcmp function is used to compare strings. The strcmp function compares two strings based on the ASCII code . If the two strings are exactly equal, it returns 0; if the first string is greater than the second string, it returns a value greater than 0; if the first string is less than the second string, it returns a value less than 0 Numerical value.
Legendary source code : (just look at the principle)

int __cdecl strcmp (const char * src, const char * dst)
{
    
    
    int ret = 0 ;
    while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
                ++src, ++dst;  
    if ( ret < 0 )
           ret = -1 ;
    else if ( ret > 0 )
           ret = 1 ;
    return( ret );
}

Adaptation :
In order to reduce the limitation of function parameter transfer, the following changes have been made, mainly for judging the character situation, see the comment. Regarding the comparison of the size, there are not many non-zero values ​​returned when using it, mainly depending on whether equal

int str_cmp(void *str1,void *str2)
{
    
    
	uint8_t * str_1=(uint8_t*) str1;//强制转化
	uint8_t * str_2=(uint8_t*) str2;
	
	if((*str_1)=='\0'&&(*str_2)=='\0')
	{
    
    
		printf("都为空");
		return 0;
	}
	else 
	{
    
    
		while(*str_1==*str_2)
	    {
    
    
	    	str_1++;
	    	str_2++;
	    	if(*str_1==*str_2&&*str_1=='\0')
	    	{
    
           printf("不为空,且相等");
	    			return 2;
	    			
			}
		}
		printf("不为空,但是不相等");
		return 1;
	}
	
}

int strlen(const char * const s)

Source code

int strlen(const char * const s)

{
    
    
int i;

for (i = 0; s[i]; i++) ;

return i;

}

Adaptation:
Three adaptations, which are commonly used cases, recursive calls, pointer writing , and self-understanding

int str_len1(void *str)//一般调用 
{
    
    
	uint8_t *st=(uint8_t*)str;
	uint8_t i=0;
	while(*st++!='\0')
	{
    
    
		i++;
	}
	return i;
}
int str_len2( void  *str)//递归调用 
{
    
    
	uint8_t *st=(uint8_t *)str;
	return (*st!='\0'?(1+str_len2(st+1)):0);	
} 
int str_len3(void *str)//指针写法 
{
    
    
	uint8_t *st=(uint8_t*)str;
	while(*st!='\0')
	{
    
    
		st++;
	}
	return  st-str;
}

char * __cdecl strstr(const char *str1, const char *str2)

The strstr() function accepts two pointers to strings as parameters. If the second string is contained in the first string, the function will return the address where the first string starts. If there is no corresponding substring, NULL is returned.
Source code

char * __cdecl strstr(const char *str1, const char *str2)
{
    
    
    char *cp = (char *)str1;
    char *s1, *s2;if (!*str2)
        return((char *)str1);while (*cp)
    {
    
    
        s1 = cp;
        s2 = (char *)str2;while (*s2 && !(*s1 - *s2))
            s1++, s2++;if (!*s2)
            return(cp);
​
        cp++;
    }return(NULL);
}

Adaptation:
1) The use of recursive call
uint8_t pay attention to call the header file.
Idea:
Start traversing and search in the parent string based on the first string of the substring. Once the first identical character is found, start to count the length of the string Compare, if it meets, this string is the first string that meets the conditions in the parent string, otherwise, if it does not meet the call back to this function, the incoming parent string address is increased

uint8_t *str_(void *str_1,void *str_2)
{
    
    
	uint8_t *str1=(uint8_t*) str_1;
	uint8_t *str2=(uint8_t*) str_2;
	int len;
	uint8_t i;
	len=(uint8_t)str_len2(str_2);
	
	while(*str1!=*str2)
	{
    
    
		str1++;
		if(*str1=='\0')
		{
    
    
			return (NULL);
		}
		
	}
	for(i=0;i<len;i++)
	{
    
    
		if(*str1==*str2)
		{
    
    
			str1++;
			str2++;
		}
		else
		{
    
    
			str_(str1,str_2);
		}
	}
	return str1-len;
}

2) The idea of ​​adapting according to the source code
Idea:
First judge two strings, if one of them is empty, then return NULL, and traverse from the parent string

uint8_t *str_str(void *str_1,void *str_2)
{
    
    
	uint8_t *str1=(uint8_t*) str_1;
	uint8_t *str2=(uint8_t*) str_2;
	uint8_t *cp;
	uint8_t len;
	uint8_t i;
	len=str_len2(str_2);
	if(str_len2(str_2)==0||str_len2(str_1)==0)
	{
    
    
		return NULL;
	}
	while(*str1)
	{
    
    
		cp=str1;
		if(*cp==*str2)
		{
    
    
			for(i=0;i<len;i++)
			{
    
    
				if(*cp==*str2)
				{
    
    
					cp++;
			        str2++;
				}
				else
				{
    
    
					break;
				}
				
				return str1;
			
			}
			
		}
		
		str1++;
	}
	return NULL;
} 

Others
The pursuit of source code cannot be reduced. Such an algorithm is very classic, and it is worth imitating and learning.

Guess you like

Origin blog.csdn.net/weixin_42271802/article/details/105739192