我是靠谱客的博主 想人陪枫叶,最近开发中收集的这篇文章主要介绍常见字符串函数,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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

// 内存copy函数
void *my_memcpy(void *dest, const void *src, int n)
{
    assert((NULL != dest) && (NULL != src));    //判断指针的有效性
    char *pdest = (char *)dest;              
    char *psrc = (char *)src;       //转换成char类型,一个字节一个字节的传输
    while(n--)
        *pdest++ = *psrc++;     //每次传输一字节
    return pdest;
}

/**
 * memcpy在内存没有重复的情况下能够正确复制,若有重叠情况则复制结果错误,但是它的效率比memmove高。
 * 所以,在确定没有重复的情况下用memcpy,在不确定是否有内存重复的情况用memmove。
 */
void *my_memmove(void *dest, const void *src, int n)
{
    assert((NULL != dest) && (NULL != src));
    char *pdest = (char *)dest;                 //转换成char类型,一个字节一个字节的传输
    char *psrc = (char *)src;   
    if((pdest <= psrc) || (pdest >= psrc + n))  //从前往后复制,则不会出现覆盖src中没有复制的内容
    {
        while(n--)
            *pdest++ = *psrc++;
    }
    else
    {
        pdest = pdest + n -1;   //有内存重叠时,从高字节开始传输
        psrc = psrc + n -1;     //移动到末尾
        while(n--)
        *pdest-- = *psrc--; //每次移动一个字节
    }
    return pdest;
}

// 作用:将已开辟内存空间 s 的首 n 个字节的值设为值 c。
void *my_memset(void *s, int c, int n)
{
    assert(NULL != s);
    unsigned char *buff = (char *)s;
    while(n--)
    {
        *(buff++) = (char)c;
    }
    return buff;
}

/** memcmp函数会逐字节比较s1和s2所指内存区,
 * s1 > s2 —-> 返回 >0 的值 
 * s1 = s2 —-> 返回 =0 的值 
 * s1 < s2 —-> 返回 <0 的值
 */
int my_memcmp(const void *s1, const void *s2, int n)
{
    assert((NULL != s1) && (NULL != s2));

    int result;
    while(!(result = *(unsigned char *)s1 - *(unsigned char *)s2) && (n--))
    {
        s1++; s2++;
    }
    return result;
    
}

// 当第一次遇到字符c时停止查找。如果成功,返回指向字符c的指针;否则返回NULL。
void *my_memchr(const void *s, int c, int n)
{
    assert(NULL != s);
    int result;
    while((*(unsigned char *)(s) != (unsigned char)c) && (n--))
    {
        s++;
    }
        return (n ? (void *)s : NULL);
}

char *my_strcpy(char *dest, const char *src)
{
    assert((NULL != dest) && (NULL != src));//判断指针的有效性
    char *addr = dest;
    while((*dest++ = *src++) != '');
    return addr;            //返回 char *,使函数支持链式表达式
}

char *my_strncpy(char *dest, const char *src, int n)
{
    assert((NULL != dest) && (NULL != src));
    char *addr = dest;
    while((n--) && (*dest++ = *src++) != '');
    return addr;            //返回 char *,使函数支持链式表达式
}

char *my_strcat(char *dest, const char *src)
{
    assert((NULL != dest) && (NULL != src));
    char *addr = dest;
    while(*dest!= '') //若使用while(*strDest++),则会出错,因为++是不受循环约束的
    {
        *dest++;    //要使dest最后指向该字符的结束标志,就必须在内部循环
    }
    while((*dest++ = *src++) != '');
    return addr;    //为了实现链式操作,将目的地址返回
}

/**
 * my_strncat其原理与my_strcat相同,只是在判断条件中加入边界条件;
 * while(((i++ < n) && (*dest++ = *src++)) != '')中,i++<n 为边界,当i = n-1时,退出循环
 */
char *my_strncat(char *dest, const char *src, int n)
{
    assert((NULL != dest) && (NULL != src));
    char *addr = dest;
    while(*dest != '')
    {
        *dest++;
    }
    while((n--) && (*dest++ = *src++) != '');
    return addr;
}

/**
 * 使用*(unsignedchar*)str1而不是用*str1。这是因为传入的参数为有符号数,有符号字符值的范围
 * 是-128~127,无符号字符值的范围是0~255,而字符串的ASCII没有负值,若不转化为无符号数这回在
 * 减法实现时出现错误。例如str1的值为1,str2的值为255。
 *
 * While循环中(!(result = *(unsigned char *)s1 - *(unsigned char *)s2) && *s1),最后与上str1
 * 也可以换成str2,因为前面已经做了相减,无论哪个先为‘’都会退出。因为最后与上str1是为了判
 * 断str1是否结束,即是否为‘’。
 */
int my_strcmp(const char *s1, const char *s2)
{
    assert((NULL != s1) && (NULL != s2));
    int result;
    while(!(result = *(unsigned char *)s1 - *(unsigned char *)s2) && *s1)
    {
        s1++; s2++; //字符串比较是一位一位的比较,s1++,s2++的作用是循环比较下一位
    }
    if(result > 0) {return 1;}
    else if(result < 0) {return -1;}
    else {return 0;}
}

/**
 * my_strncmp的实现原理与my_strcmp相同,但是相对于my_strcmp多了边界条件n;
 */
int my_strncmp(const char *s1, const char *s2, int n)
{
    
    assert((NULL != s1) && (NULL != s2));
    int result;
    while(!(result = *(unsigned char *)s1 - *(unsigned char *)s2) && *s1 && (n--))
    {
        s1++; s2++;
    }
    if(result > 0) {return 1;}
    else if(result < 0) {return -1;}
    else {return 0;}

}

char *my_strchr(const char *s, int c)
{
    assert(NULL != s);
    while(*s != (char)c)
    {   
        if ( *s == '' )
			return NULL;
		s++;
    }
	return (char *)s;

}
int my_strlen(const char *str)
{
    assert(NULL != str);
    int len = 0;
    while(*str++ != '')   //strlen计算字符长度是不计算''的,这是函数原型决定的
    {
        len++;
    }
    return len;
}
char *my_strdup(const char *src)
{
    assert(NULL !=src);
    char *psrc = (char *)src;
    char *p_src = NULL;
    p_src = psrc ;
    int len = 0 + 1;
    while(*p_src++ != '')
         len++;
    p_src = psrc;
    char *new_addr  = (char *)malloc(sizeof(char)*(len));
    while((*new_addr++ = *p_src++)  != '');
    return (new_addr - len);
}

char *my_strndup(const char *s, int n)
{
    assert(NULL != s);
    
}

//搜索一个字符串 *needle 在 *haystack 字符串中的第一次出现。
char *my_strstr(const char *haystack, const char *needle)
{
    assert((NULL != haystack) && (NULL != needle));
    while(*haystack++ !='')
    {
        if((*haystack - *needle) == 0)
            return (char *)haystack;
        haystack++;
    }
    return NULL;
}

char *my_strtok(char *str, const char *delim)
{
    
}
int my_strcoll(const char *s1, const char *s2)
{
    
}

int main(void)
{
    char dest[20] = {}, src[] = "abcde";
    char dest1[20] = {}, src1[] = "linux";

/*    //my_memcpy功能验证
    printf("my_strcpy= %sn", my_strcpy(dest1, src1));
    printf("strcpy   = %sn", strcpy(dest, src));

    // memcpy(dest+2, dest, 5); 
    // printf("memcpy   = %sn", dest);//输出:my_memcpy  = abababa
    // memcpy(dest, dest1, strlen(dest1)); 
    // printf("memcpy   = %sn", dest);//输出:my_memcpy  = linuxba  

    my_memcpy(dest+2, dest, 5); 
    printf("my_memcpy= %sn", dest);//输出:my_memcpy  = abababa
    my_memcpy(dest, dest1, strlen(dest1)); 
    printf("my_memcpy= %sn", dest);//输出:my_memcpy  = linuxba      
*/ 

/*    //my_memmove功能验证
    printf("my_strcpy= %sn", my_strcpy(dest1, src1));
    printf("strcpy   = %sn", strcpy(dest, src));

    // memmove(dest+2, dest, 5); 
    // printf("memmove  = %sn", dest);    //输出:memmove  = ababcde
    // memmove(dest, dest1, strlen(dest1)); 
    // printf("memmove  = %sn", dest);    //输出:memmove  = linuxde
     
    my_memmove(dest+2, dest, 5);
    printf("my_memmove  = %sn", dest);//输出:my_memmove  = ababcde
    my_memmove(dest, dest1, strlen(dest1)); 
    printf("my_memmove  = %sn", dest);//输出:my_memmove  = linuxde            
*/   

/*    //my_memset功能验证
    my_memset(dest, '2', 20);
    printf("my_memset  = %sn", dest);  //输出:22222222222222222222
    memset(dest, 'A', 5);
    printf("memset     = %sn", dest);  //输出:AAAAA222222222222222
*/

/*    //my_memcmp功能验证
    printf("dest1     = %sn", my_strncpy(dest1, src1,5));  //dest1 = linux
    printf("dest      = %sn", my_strncpy(dest, src, 5));   //dest  = liabc
    
    printf("my_memcmp = %dn", my_memcmp(dest1, dest, 2));
    printf("memcmp    = %dn", memcmp(dest1, dest, 3));

*/

/*    //my_memchr功能验证

    printf("dest  = %sn", my_strcpy(dest, "arm - linux - gcc"));
    printf("dest1 = %sn", my_strcpy(dest1, "gcc"));
 
    printf("dest1:%s =%sn",dest1,(char *)memchr(dest,'-',my_strlen(dest)));
    printf("dest1:%s =%sn",dest1,(char *)my_memchr(dest,'-',my_strlen(dest)));
*/

/*    //my_strcpy功能验证
    printf("my_strcpy  = %sn", my_strcpy(dest1, src1));
    printf("strcpy     = %sn", strcpy(dest, src));
*/

/*    //my_strncpy功能验证
    printf("my_strncpy = %sn", my_strncpy(dest1, src1, 5));
    printf("strncpy    = %sn", strncpy(dest, src, 5));
*/


/*    //my_strcat功能验证
    printf("my_strncpy = %sn", my_strncpy(dest1, src1, 2));
    printf("my_strcat  = %sn", my_strcat(dest1, src1));
    printf("strcat     = %sn", strcat(dest1, src));
*/

/*    //my_strncat功能验证
    printf("my_strncpy = %sn", my_strncpy(dest1, src1, 2));
    printf("my_strncat = %sn", my_strncat(dest1, src1, 2));
    printf("strncat    = %sn", strncat(dest1, src, 2));
*/

/*    //my_strcmp功能验证
    printf("my_strncat = %sn", my_strncat(dest1, src1, 3));
    printf("my_strncat = %sn", my_strncat(dest, src1, 2));
    printf("my_strcmp  = %dn", my_strcmp(dest1, dest));
    printf("   strcmp  = %dn", strcmp(dest1, dest));
    printf("my_strcmp  = %dn", my_strcmp(src, src1));
    printf("   strcmp  = %dn", strcmp(src, src1));
*/

/*    //my_strncmp功能验证
    printf("my_strncpy  = %sn", my_strncpy(dest1, src1,5));
    printf("my_strncpy  = %sn", my_strncpy(dest, src, 5));
    printf("my_strncmp  = %dn", my_strncmp(dest1, dest, 1));
    printf("   strncmp  = %dn", strncmp(dest1, dest, 1));
    printf("my_strncmp  = %dn", my_strncmp(src, src1, 1));
    printf("   strncmp  = %dn", strncmp(src, src1, 1));
*/

/*    //my_strchr功能验证
    char *dest2 = "arm-linux-gcc";
    
    printf("strchr    = %sn", strchr(dest2, 'r'));
    printf("my_strchr = %sn", my_strchr(dest2, 'r'));
*/

    
/*    //my_strlen功能验证
    printf("my_strncpy = %sn", my_strncpy(dest1, src1, 5));
    printf("my_strlen  = %dn", my_strlen(dest1));
    printf("strlen     = %dn", strlen(dest1));  
*/

/*    //my_strdup功能验证
    char *src2 = "arm-linux-gcc";
    char *dest2 , *dest3;
    dest2 = strdup(src2);
    dest3 = my_strdup(src2);
    printf("strdup string is: %sn", dest2);
    printf("strdup string is: %pn", dest2);
    printf("my_strdup string is: %sn", dest3);
    printf("my_strdup string is: %pn", dest3);
    free(dest2);
    free(dest3);
*/

/*    //my_strndup功能验证
    char *src2 = "arm-linux-gcc";
    char *dest2 , *dest3;
    dest2 = strndup(src2, 2);
    dest3 = my_strndup(src2, 2);
    printf("strndup string is: %sn", dest2);
    printf("strndup string is: %pn", dest2);
    printf("my_strndup string is: %sn", dest3);
    printf("my_strndup string is: %pn", dest3);
   // free(dest2);
   // free(dest3);
*/

///*    //my_strstr功能验证
    char *src2 = "arm-linux-gcc";
    char *dest2= "ux";
    char *dest3, *dest4;

    dest3 = my_strstr(src2, dest2);
    dest4 = strstr(src2, dest2);
    printf("strstr string is: %sn", dest3);
    printf("my_strstr string is: %sn", dest4);
//*/




    return 0;
}
































最后

以上就是想人陪枫叶为你收集整理的常见字符串函数的全部内容,希望文章能够帮你解决常见字符串函数所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部