字符串操作函数(strcpy/strcmp/strcat/strstr/strchr/memcpy/memmove)

字符串操作函数的实现


前言
  • 实现strcpy
  • 实现strcat
  • 实现strstr
  • 实现strchr
  • 实现strcmp
  • 实现memcpy
  • 实现memmove

strcpy的实现
  • 函数原型

char *MyStrcpy(char *dest, const char *src);

  • 实现代码
//该函数不能处理内存重叠现象,故出现了函数memcpy();
//实现strcpy
char *MyStrcpy(char *dest, const char *src) //1.原字符串设置成const,防止被修改;2.返回值为char *,链式访问         
{
    assert(dest && src);                    //3.增强代码健壮性
    char *ret = dest;                       //4.同时将\0也拷贝入内。
    while (*ret++ = *src++);    
    return dest;
}
strcat的实现
  • 函数原型

char* MyStrcat(char *dest, const char *src);

  • 实现代码
char* MyStrcat(char *dest, const char *src)
{
    assert(dest&&src);
    char *ret = dest;
    while (*ret)
    {
        ret++;
    }
    while (*ret++ = *src++);

    return dest;
}
strstr的实现
  • 函数原型

char* MyStrstr(const char *str1,const char *str2);

  • 实现代码
char* MyStrstr(const char *str1,const char *str2)
{
    assert(str1&&str2);
    while (*str1)
    {
        if (*str1 == *str2)
        {
            const char *tmp1 = str1;
            const char *tmp2 = str2;
            while (*tmp1 == *tmp2)
            {
                tmp1++;
                tmp2++;
            }
            if (*tmp2 == '\0')
            {
                return str1;
            }
        }
        str1++;
    }
    return NULL;
}
strchr的实现
  • 函数原型

char *MyStrchr(const char *dest, char c);

  • 实现代码
char *MyStrchr(const char *dest, char c)
{
    assert(dest);
    while (*dest)
    {
        if (*dest == c)
        {
            return dest;
        }
        dest++;
    }
    return NULL;
}
strcmp的实现
  • 函数原型

int MyStrcmp(const char *str1, const char *str2);

  • 实现代码
int MyStrcmp(const char *str1, const char *str2)
{
    assert(str1 && str2);
    while (*str1 == *str2&&*str1 != '\0')          //优化版本
    {
        str1++;
        str2++;
    }
    if (*str1 == '\0'&&*str2 == '\0')
    {
        return 0;
    }
    else if (*str1 > *str2)
    {
        return 1;
    }
    else
    {
        return -1;
    }

    /*while (*str1 != '\0'&&*str2 != '\0')        //正常思路
    {
        if (*str1 > *str2)
        {
            return 1;
        }
        else if (*str1 < *str2)
        {
            return -1;
        }
        str1++;
        str2++;
    }
    if (*str1 == '\0'&&*str2 == '\0')
    {
        return 0;
    }
    else if (*str1 == '\0')
    {
        return -1;
    }
    return 1;*/
}
memcpy的实现
  • 函数原型

void *MyMemcpy(void *dest, const void *src,size_t size);

  • 实现代码
//size表示字节数,此函数可实现任意类型,例如字符数组、整型、结构体、类等
void *MyMemcpy(void *dest, const void *src,size_t size)
{
    assert(dest&&src);
    char* tmp = (char *)dest;

    while (size--)
    {
        *tmp++ = *((char *)src)++;
    }

    return dest;
}
memmove的实现
  • 函数原型

void *MyMemmove(const void *deststr, const void *srcstr, size_t size);

  • 实现代码

//考虑了内存重叠问题
void *MyMemmove(const void *deststr, const void *srcstr, size_t size)
{
    assert(deststr&&srcstr);

    if (deststr == srcstr)
    {
        return deststr;
    }

    else if (deststr < srcstr||deststr >=(char *)srcstr+size)
    {
        char *dest = (char *)deststr;
        char *src = (char *)srcstr;
        while (size--)
        {
            *dest++ = *src++;
        }
        return deststr;
    }
    else                            //内存重叠,从后向前拷贝
    {
        char *dest = (char *)deststr+size-1;  //注意:向后偏移size+1(即:区间长度)
        char *src = (char *)srcstr + size-1;
        while (size--)
        {
            *dest-- = *src--;
        }
        return deststr;
    }
}
总结

strcpy和memcpy主要有以下3方面的区别:

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

附加测试代码
/以 下 为 测 试 代 码/ 
#define TEST_HEADER printf("==========================%s==========================\n",__FUNCTION__)


void TestStrcpy()
{
    TEST_HEADER;
    char dest[10] = "abcdef";
    printf("%s\n", MyStrcpy(dest, "hallo"));          //正常输出
    //printf("%s\n", MyStrcpy(dest+2, dest));         //不能处理内存重叠
}

void TestStrcmp()
{
    TEST_HEADER;
    char str1[10] = "abcdef";
    char str2[10]="abcdef";
    printf("dest:%s,src:%s\n",str1, str2);
    printf("ret expect is 0,real is %d\n", MyStrcmp(str1, str2));
}

void TestStrcat()
{
    TEST_HEADER;
    char dest[10] = "abcde";
    char src[5] = "fgh";
    printf("dest:%s,src=%s\n", dest, src);
    printf("dest expect is abcdefgh,actual is %s\n", MyStrcat(dest, src));
}
void TestStrchr()
{
    TEST_HEADER;
    char dest[10] = "abcdefghi";
    printf("dest:%s\n", dest);
    printf("dest expect is %p,actual is %p\n", &dest[4], MyStrchr(dest, 'e'));
}

void TestStrstr()
{
    TEST_HEADER;
    char dest[10] = "abcdefghi";
    char src[4] = "fgh";
    printf("dest:%s,src=%s\n", dest, src);
    printf("dest expect is %p,actual is %p\n", &dest[5], MyStrstr(dest, src));
}

void TestMemcpy()
{
    TEST_HEADER;
    /*char dest[20] = "abcdefg";
    char src[20] = "hello world!";

    printf("dest:%s,src=%s\n", dest, src);
    printf("dest expect is hello,actual is %s\n",MyMemcpy(dest, src,5));
*/
    int dest[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    int src[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
    int i = 0;
    MyMemcpy(dest, src, 10*sizeof(int));
    for (i = 0; i < 10; i++)
    {
        printf("%d\t", dest[i]);
    }
}

void TestMyMemmove()
{
    TEST_HEADER;
    char str1[20] = "hello world!";
    char str2[20] = "hello world!";
    char str3[20] = "hello world!";


    MyMemmove(str1, str1 + 2, 5);
    MyMemmove(str2+2, str2, 5);
    MyMemmove(str3+2, str3, 2);

    printf("str1 expect is llo w world! ,actual is %s\n", str1);
    printf("str2 expect is hehelloorld! ,actual is %s\n", str2);
    printf("str3 expect is heheo world! ,actual is %s\n", str3);
}

void TestStdio()
{
    TEST_HEADER;
    //char dest[20] = "abcdefg";
    //char src[20] = "hello world!";
    //printf("dest:%s,src=%s\n", dest, src);
    //printf("dest expect is hello,actual is %s\n", memcpy(dest, src, 5));

    /*int dest[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    int src[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
    int i = 0;
    memcpy(dest, src, 4*sizeof(int));
    for (i = 0; i < 10; i++)
    {
        printf("%d\t", dest[i]);
    }
    printf("\n");*/

    char str1[20] = "hello world!";
    char str2[20] = "hello world!";
    char str3[20] = "hello world!";


    memmove(str1, str1 + 2, 5);
    memmove(str2 + 2, str2, 5);
    memmove(str3 + 2, str3, 2);

    printf("str1 expect is llo w world! ,actual is %s\n", str1);
    printf("str2 expect is hehelloorld! ,actual is %s\n", str2);
    printf("str3 expect is heheo world! ,actual is %s\n", str3);

}
int main()
{
    TestStrcpy();
    TestStrcmp();
    TestStrcat();
    TestStrchr();
    TestStrstr();
    TestMemcpy();
    TestMyMemmove();
    TestStdio();

    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值