Procesamiento de caracteres strlen (), strcmp (), strstr () código fuente y adaptación

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

La función strcmp se utiliza para comparar cadenas, mientras que la función strcmp compara dos cadenas según el código ASCII . Si las dos cadenas son exactamente iguales, devuelve 0; si la primera cadena es mayor que la segunda cadena, devuelve un valor mayor que 0; si la primera cadena es menor que la segunda cadena, devuelve un valor menor que 0 Numérico valor.
Código fuente legendario : (solo mire el principio)

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 );
}

Adaptación :
Para reducir la limitación de la transferencia de parámetros de función, se han realizado los siguientes cambios, principalmente para juzgar la situación del carácter, ver el comentario. Con respecto a la comparación del tamaño, no se devuelven muchos valores distintos de cero cuando usándolo, principalmente dependiendo de si es igual

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)

Código fuente

int strlen(const char * const s)

{
    
    
int i;

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

return i;

}

Adaptación:
Tres adaptaciones, que son casos de uso común, llamadas recursivas, escritura de punteros y autocomprensión.

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)

La función strstr () acepta dos punteros a cadenas como parámetros. Si la segunda cadena está contenida en la primera cadena, la función devolverá la dirección donde comienza la primera cadena. Si no hay una subcadena correspondiente, se devuelve NULL.
Código fuente

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);
}

Adaptación:
1) El uso de la llamada recursiva
uint8_t preste atención para llamar al archivo de encabezado.
Idea:
Empiece a recorrer y busque en la cadena principal basándose en la primera cadena de la subcadena. Una vez que encuentre el primer carácter idéntico, comience a contar la longitud de la cadena Compare, si cumple, esta cadena es la primera cadena que cumple con las condiciones en la cadena principal; de lo contrario, si no cumple con la llamada a esta función, la dirección de la cadena principal entrante aumenta

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) La idea de adaptarse de acuerdo con el código fuente
Idea:
Primero juzgue dos cadenas, si una de ellas está vacía, luego devuelva NULL y atraviese desde la cadena principal

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;
} 

Otros
La búsqueda del código fuente no se puede reducir, un algoritmo de este tipo es muy clásico y vale la pena imitarlo y aprenderlo.

Supongo que te gusta

Origin blog.csdn.net/weixin_42271802/article/details/105739192
Recomendado
Clasificación