C语言常见字符串函数实现

/*
熟练使用C语言中提供的代码库有助于我们在编程时极大减少工作量和一些没有必要的bug。
想成为一个优秀的程序员,必须深入理解这些库。而编写这些库就是最好的学习手段。
在平常的积累中,也可以自己扩展库,逐步增强自身能力。
下面实现了一些工作中常用到的C语言库函数。
*/
# include <stdio.h>
# include <malloc.h>  //包含了malloc函数
# include <stdlib.h>  //包含了exit函数


//功能:初始化内存块
//返回值:指向内存块的指针
void *memsetTest(void *s,int c,size_t count)
{
    unsigned char uc = (unsigned char)c;
    unsigned char *ucps = (unsigned char *)s;
    while(count--)
        *ucps++ = uc;
        return s;
}
//功能:复制内存块
//返回值:指向目的地址的指针
//缺点:没有考虑内存重叠的情况
void *memcpyTest(void *dest,const void *src,size_t count)
{
    if(dest == NULL || src == NULL)
    {
        return NULL;
    }
    char *pDest = (char *)dest;
    char *pSrc = (char *)src;
    while(count>0)
    {
        *pDest++  = *pSrc++;
        count--;
    }
    return dest;
}
//功能:复制内存块
//返回值:指向目的地址的指针
//有考虑到内存重叠的情况
void *memmoveTest(void *dest,const void *src,size_t count)
{
    char *pDest = (char *)dest;
    char *pSrc = (char *)src;
    if (dest == NULL || src == NULL)
    {
        return NULL;
    }
    if (dest < src)//从源位置的第一个元素开始复制 
    {
        while(count-- > 0)
        {
            *pDest++ = *pSrc++;
        }
    }
    else//从源位置最后一个元素开始复制 
    {
        pDest = pDest + count -1;
        pSrc = pSrc + count -1;
        while(count-- > 0)
        {
            *pDest-- = *pSrc--;         
        }
    }
    return dest;
}
//功能:比较内存块
int memcmpTest(const void *buf1,const void *buf2,size_t count)
{
    while(count-- && ( *((char *)buf1) == *((char *)buf2) ))
    {
        buf1 = (char *)buf1 + 1;
        buf2 = (char *)buf2 + 1;
    }
    return (*((unsigned char *)buf1) - *((unsigned char *)buf2));
}
//功能:字符串复制
char *strcpyTest(char *dest,const char *src)
{
    if(dest == NULL || src == NULL)
    {
        return NULL;
    }
    char *pTmp = dest;
    while(*pTmp++ = *src++);
    return dest;

}
//功能:有限制的字符串复制
char *strncpyTest(char *dest,const char *src,size_t count)
{
    int i = 0;
    char *pTmp = dest;
    if(dest == NULL || src == NULL)
    {
        return NULL;
    }
    for(i = 0;i < count; i++)
    {
        if (*src == '\0')
        {
            return NULL;
        }
        *pTmp++ = *src++;
    }
    if(*pTmp != '\0')
        *pTmp = '\0';
    return dest;
}

//功能:有限制的字符串的连接
//返回值:返回s1(指向连接后字符串的指针)
char *strncatTest(char *front,const char *back, size_t count)
{
    char *pStart = front;
    while(*front != '\0')
    {
        front++;
    }

    while (count--)
    {
        if( !( *front++ = *back++) )
            return pStart;
    }
    *front = '\0';
    return pStart;
}
//功能:比较字符串
//返回值:
//       returns -1 if src <  dest
//       returns  0 if src == dest
//       returns +1 if src >  dest
int strcmpTest(const char *src, const char *dest)
{
    unsigned char *pSrc = (unsigned char *)src;
    unsigned char *pDest = (unsigned char *)dest;
    int ret;
    while(*pSrc != '\0')
    {
        ret = *pSrc++ - *pDest++;
        if(ret && *pDest)
        {
            break;
        }
    }
    if (ret < 0)
        return -1;
    else if (ret == 0)
        return 0;
    else if (ret > 0)
        return 1;
}
//比较字符串,精简版,代码优化 
int strcmpTest_1(const char *src, const char *dest)
{
    unsigned char *pSrc = (unsigned char *)src;
    unsigned char *pDest = (unsigned char *)dest;
    int ret = 0;
    while(*pSrc != '\0')
    {
        ret = *pSrc++ - *pDest++;
        if(ret && *pDest)
        {
            break;
        }
    }
    if (ret < 0)
        ret = -1;
    else if (ret > 0)
        ret = 1;
    return ret; 
}

//比较字符串前count字节 
//       returns <0 if src < dest
//       returns  0 if src == dest
//       returns >0 if src > dest
int strncmpTest(const char *src, const char *dest, size_t count)
{
    unsigned char *pSrc = (unsigned char *)src;
    unsigned char *pDest = (unsigned char *)dest;
    int ret = 0;
    while((count-- > 0)&& *pSrc)
    {
        ret = *pSrc++ - *pDest++;
        if(ret && *pDest)
        {
            break;
        }
    }
    return ret; 
}

//功能:查找某字符在字符串中首次出现的位置
//返回值:返回字符串首次出现c的位置的指针如果Str中不存在Val则返回NULL
char *strchrTest(const char *s, int c)
{
    while (*s != '\0')
    {
        if (*s == (char)c)
        {
            return (char *)s;
        }
        s++;
    }
    return NULL;
}

//函数:查找一个字符c在另一个字符串s中末次出现的位置
//(也就是从str的右侧开始查找字符c首次出现的位置),
//返回值:这个位置的地址。如果未能找到指定字符,那么函数将返回NULL。
char *strrchrTest(const char *s, int c)
{
    char *pStart = (char *)s;
    while(*s != '\0')
    {
        s++ ;
    }
    --s;
    while(s >= pStart)
    {
        if (*s == c)
        {
            return (char *)s;
        }
        s--;
    }
    return NULL;
}
//功能:计算字符串长度
size_t strlenTest(const char *str)
{
    int length = 0;
    while(*str++)
        length++;
    return length;
}

// 功能:判断str2是否在str1中 
// 返回值:返回子字符串string2在string1中的地址,如果没有找到返回NULL
char *strstrTest(const char *str1, const char *str2)
{
    char *pStr1 = (char *)str1;
    char *pStr2 = (char *)str2;
    char *pSign = NULL;//记录子串的开始位置 
    if ( !*str2 )
        return((char *)str1);
    while (*pStr1++)
    {
        pSign = pStr1; 
        //是否子串所有元素都相等 
        while(*pStr1 && *pStr2 && !(*pStr1 - *pStr2))
        {
            pStr1++;
            pStr2++;
            if(*pStr2 == '\0')
            {
                //找到子串 
                return pSign;
            }
        }
        //子串没有全部相等,重新 给pStr赋值 
         pStr2 =  (char *)str2; 
    }
    return NULL;
}
//功能:分割字符串
//微软实现
char*  strtok_r(char* string_org,const char* demial)
{
    static unsigned char* last; //保存分隔后剩余的部分
    unsigned char* str;         //返回的字符串
    //分隔字符
    const unsigned char* ctrl = (const unsigned char*)demial;

    //把分隔字符放到一个索引表中。
    //定义32是因为ASCII字符表最多是0~255个,也是说用大的255右移3位,
    //也就是除以8一定会是32中的一个数。
    unsigned char map[32]; 
    int count;

    //把map全部清为0,之后相与的操作,与0的都为0
    for (count =0; count <32; count++)
    {
        map[count] = 0;
    }

    //把匹配字符放入表中
    //放入的算法是把匹配字符右移3位,相当于除以8,的数值 并上(加上)
    //匹配字符与7,得到低3位,得出的结果,是把1左移的位数。
    //最大左移位数是7,也就所表示的最大值是128,    
    do 
    {
        map[*ctrl >> 3] |= (1 << (*ctrl & 7));
    } while (*ctrl++);

    //原始字符串是否为空,如果为空表示第二次获取剩余字符的分隔部分。    
    if (string_org)
    {
        str = (unsigned char*)string_org;
    } 
    else
    {
        str = last;
    }
    //在表中查找是否有匹配的字符,如果有略过    
    while ((map[*str >> 3] & (1 << (*str & 7)))  && *str)
    {
        str++;
    }

    //重置需要扫描的字符串    
    string_org = (char*)str;

    //开始扫描
    for (;*str; str++)
    {
        if ( map[*str >> 3] & (1 << (*str & 7)))
        {
             *str++ = '\0';//当找到时,把匹配字符填为0,并且把str指向下一位。
              break; //退出循环             
        }

    }

    last =str; // 把剩余字符串的指针保存到静态变量last中。

    if (string_org == (char*)str)
        {
            return NULL; //没有找到,也就是没有移动指针的位置,返回NULL
        }
    else
        {
            return string_org; //找到了,返回之前字符串的头指针
        }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值