编写C语言的字符串拷贝函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编写C语言的字符串拷贝函数相关的知识,希望对你有一定的参考价值。

参考技术A 编写程序,实现两个字符串拷贝的函数strcopy。
要求:
不允许使用C的字符串函数strcpy。
主程序中从键盘输入两个字符串。调用strcopy函数实现字符串拷贝操作。
输出拷贝前后,两个字符串的内容。

C语言 字符串操作函数及内存拷贝函数归总

今天在这里把零散的一些常用的字符串操作函数和内存拷贝函数进行一下归总实现。


一 . 字符串操作函数


字符串操作函数有很多,这里我列举一些常用的函数,以及自实现的代码:

字符串拷贝函数:

函数原型:

char* my_strcpy(char* dst,const char* src)

strcpy():

char* my_strcpy(char* dst,const char* src)

    assert(dst);
    assert(src);

    char *ret = dst;  //把首地址保存起来,因为下面会修改dst
    while (*dst++ = *src++)
        ;

    return ret;

函数原型:

char* my_strncpy(char* dst,const char* src,int n)

strncpy():

char* my_strncpy(char* dst,const char* src,int n)

    assert(dst);
    assert(src);

    char* ret = dst;
    while (n--)
    
        *dst++ = *src++;
    

    return ret;

字符串追加函数:

函数原型:

char* my_strcat(char* dst,const char* src)

strcat():

char* my_strcat(char* dst,const char* src)

    assert(dst);
    assert(src);

    char *ret = dst;

    while (*dst) 
        dst++;

    while (*dst++ = *src++)
        ;

    return ret;

函数原型:

char* my_strncat(char *dst, const char *src, int n)

strncat():

char* my_strncat(char *dst, const char *src, int n)

    assert(dst);
    assert(src);

    char *ret = dst;
    while (*dst)
        dst++;
    while (n--)
    
        *dst++ = *src++;
    

    return ret;

字符串比较函数:

函数原型:

int my_strcmp(const char* dst,const char* src)

strcmp():

int my_strcmp(const char* dst,const char* src)

    assert(dst);
    assert(src);

    while ((*dst == *src) && *dst && *src)
    
        dst++;
        src++;
        if (*dst == 0 && *src == 0)
        
            return 1;
        
    

    return -1;

函数原型:

int my_strncmp(char* dst, const char* src, int n)

strncmp():

int my_strncmp(char* dst, const char* src, int n)

    assert(dst);
    assert(src);

    while (n--)
    
        if ((*dst == *src) && *dst && *src)
        
            dst++;
            src++;
        
        else
        
            return -1;
        

        if (*dst == 0 && *src == 0) // 全部相同时的处理情况
        
            return 1;
        
        

    return 1; // 部分相同时的处理情况

查找子字符串函数:

函数原型:

char* my_strtsr(char* str1, char* str2)

strstr():

char* my_strtsr(char* str1, char* str2)

    assert(str1); // 原串
    assert(str2); // 子串

    char* s1 = str1;
    char* s2 = str2;
    char* s = str2; // 保存子串的首地址

    if (*s1 == 0)
    
        if (*s2)
            return NULL;

        return s;
    

    while (*s1 && *s2)
    
        if (*s1 != *s2)
        
            s1++;
        
        if (*s1 == *s2)
        
            s1++;
            s2++;
        
        if (*s1 != *s2) 
        
            if (*s1 == 0)
            
                return NULL;
            
            else if (*s2 == 0)
            
                return s;
            

            s2 = s; //若*s1和s2不相等,则让子串重新从头开始
            
    

    return NULL;





二 . 内存拷贝函数

内存拷贝函数这里罗列出 memcpy() 以及解决内存拷贝时重叠的问题的函数 memmove() ,附带写出内存初始化函数memset() .


内存拷贝函数:

函数原型:

void* my_memcpy(void *dt,const void *src,size_t count)

memcpy():

void* my_memcpy(void *dst,const void *src,size_t count)

    assert(dst);
    assert(src);

    char *pDst = (char*)dst;
    char *pSrc = (char*)src;
    char *ret = (char*)dst; // 保存dst首地址

    while (count--)
    
        *pDst++ = *pSrc++;
    

    return ret;

解决内存拷贝时 的内存重叠问题的函数:

函数原型:

void* my_memmove(void *p1,void *p2,size_t count)

memmove():

要点:判断重叠条件,只要dst的位置在src+count的范围内就会发生内存重叠

void* my_memmove(void *p1,void *p2,size_t count)

    // 在一个数组中进行
    assert(p1);
    assert(p2);

    char *dst = (char*)p1;
    char *src = (char*)p2;
    char *ret = (char*)p1; // 保存首地址

    if (dst > src && (dst < src + count)) // 判断内存重叠情况
    
        while (count--)
        
            *(dst + count) = *(src + count);
        
    
    else // 不重叠情况
    
        while (count--)
        
            *dst++ = *src++;
        
    

    return ret;

内存初始化函数:

函数原型:

void* my_memset(void* arr,int c,size_t size)

memset():

void* my_memset(void* arr,int c,size_t size)

    assert(arr);

    char* dst = (char*)arr;
    int i = 0;
    for (i = 0; i < size; i++)
    
        *(dst + i) = c;
    

    return arr;

附源代码及测试代码:

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

char* my_strcpy(char* dst,const char* src)

    assert(dst);
    assert(src);

    char *ret = dst;  //把首地址保存起来,因为下面会修改dst
    while (*dst++ = *src++)
        ;

    return ret;


char* my_strncpy(char* dst,const char* src,int n)

    assert(dst);
    assert(src);

    char* ret = dst;
    while (n--)
    
        *dst++ = *src++;
    

    return ret;



char* my_strcat(char* dst,const char* src)

    assert(dst);
    assert(src);

    char *ret = dst;

    while (*dst) 
        dst++;

    while (*dst++ = *src++)
        ;

    return ret;


char* my_strncat(char *dst, const char *src, int n)

    assert(dst);
    assert(src);

    char *ret = dst;
    while (*dst)
        dst++;
    while (n--)
    
        *dst++ = *src++;
    

    return ret;


int my_strcmp(const char* dst,const char* src)

    assert(dst);
    assert(src);

    while ((*dst == *src) && *dst && *src)
    
        dst++;
        src++;
        if (*dst == 0 && *src == 0)
        
            return 1;
        
    

    return -1;


int my_strncmp(char* dst, const char* src, int n)

    assert(dst);
    assert(src);

    while (n--)
    
        if ((*dst == *src) && *dst && *src)
        
            dst++;
            src++;
        
        else
        
            return -1;
        

        if (*dst == 0 && *src == 0) // 全部相同时的处理情况
        
            return 1;
        
        

    return 1; // 部分相同时的处理情况


char* my_strtsr(char* str1, char* str2)

    assert(str1); // 原串
    assert(str2); // 子串

    char* s1 = str1;
    char* s2 = str2;
    char* s = str2; // 保存子串的首地址

    if (*s1 == 0)
    
        if (*s2)
            return NULL;

        return s;
    

    while (*s1 && *s2)
    
        if (*s1 != *s2)
        
            s1++;
        
        if (*s1 == *s2)
        
            s1++;
            s2++;
        
        if (*s1 != *s2)
        
            if (*s1 == 0)
            
                return NULL;
            
            else if (*s2 == 0)
            
                return s;
            

            s2 = s;
            
    

    return NULL;


void* my_memcpy(void *dst,const void *src,size_t count)

    assert(dst);
    assert(src);

    char *pDst = (char*)dst;
    char *pSrc = (char*)src;
    char *ret = (char*)dst; // 保存dst首地址

    while (count--)
    
        *pDst++ = *pSrc++;
    

    return ret;


void* my_memmove(void *p1,void *p2,size_t count)

    // 在一个数组中进行
    assert(p1);
    assert(p2);

    char *dst = (char*)p1;
    char *src = (char*)p2;
    char *ret = (char*)p1; // 保存首地址

    if (dst > src && (dst < src + count)) // 判断内存重叠情况
    
        while (count--)
        
            *(dst + count) = *(src + count);
        
    
    else // 不重叠情况
    
        while (count--)
        
            *dst++ = *src++;
        
    

    return ret;


void* my_memset(void* arr,int c,size_t size)

    assert(arr);

    char* dst = (char*)arr;
    int i = 0;
    for (i = 0; i < size; i++)
    
        *(dst + i) = c;
    

    return arr;



void test1()

    char a1[10] =  0 ;
    char a2[] = "world";

    printf("%s", my_strcpy(a1, a2));
    printf("\\n");


void test2()

    char a1[15] = "hello";
    char a2[] = " world";

    printf("%s",my_strcat(a1,a2));
    printf("\\n");


void test3()

    char a1[] = "abcdef";
    char a2[] = "abcdef";
    printf("%d\\n",my_strcmp(a1,a2));


void test4()

    char a1[10] = "hello";
    char a2[] = " world";

    printf("%s",my_strncat(a1,a2,4));
    printf("\\n");


void test5()

    int a1[10] = 1,2,3,4,5,6,7,8,9,10;
    int a2[10];
    int i = 0;

    my_memcpy(a2,a1,4);
    for (i = 0; i < 10;i++)
    
        printf("%d ", a2[i]);
    
    printf("\\n");


void test6()

    int a[10] = 1,2,3,4,5,6,7,8,9,10;
    int i = 0;

    my_memmove(a+2,a+5,4);
    for (i = 0; i < 10;i++)
    
        printf("%d ",a[i]);
    
    printf("\\n");


void test7()

    char a1[10] =  0 ;
    char a2[] = "world";

    printf("%s", my_strncpy(a1, a2, 3));
    printf("\\n");


void test8()

    char a1[] = "abcdef";
    char a2[] = "acb";

    printf("%d\\n", my_strncmp(a1, a2, 2));


void test9()

    char* a1 = "abccddefgh";
    char* a2 = "cddef";

    printf("%s",my_strtsr(a1,a2));
    printf("\\n");


void test10()

    int arr[10];
    int i = 0;
    my_memset(arr, 0, 32);
    for (i = 0; i < 10; i++)
        printf("%d ",arr[i]);
    printf("\\n");


int main()

    test1();
    test2();
    test3();
    test4();
    test5();
    test6();
    test7();
    test8();
    test9();
    test10();

    system("pause");
    return 0;

若有纰漏,欢迎指正。

本文出自 “Vs吕小布” 博客,请务必保留此出处http://survive.blog.51cto.com/10728490/1769447

以上是关于编写C语言的字符串拷贝函数的主要内容,如果未能解决你的问题,请参考以下文章

自定义c语言字符串拷贝函数strcpy

c语言中strcpy跟mencpy哪个效率更高?

C语言试题184之编写一个函数,从标准输入读取一个字符串,把字符串复制到动态内存分配的内存中,并返回该字符串的拷贝,这个函数不应该对读入字符串的长度作任何限制

C语言试题184之编写一个函数,从标准输入读取一个字符串,把字符串复制到动态内存分配的内存中,并返回该字符串的拷贝,这个函数不应该对读入字符串的长度作任何限制

C语言串拷贝(strcpy)和内存拷贝(memcpy)函数有啥不同?

C 语言字符串拷贝 ( 字符串拷贝业务逻辑代码 | 分离 主函数 与 字符串拷贝 业务模型 )