strncpy&&strncat使用+模拟使用

132 阅读3分钟

「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战

长度不受限制的字符串函数

strcpy()
strcat()
strcmp()

上述三个函数不够安全 长度不受限制的字符串函数

要么就一直追加/拷贝,直到遇到\0,或者一直比较,直到遇到不相等的字符


长度受限制的字符串函数

strncpy()
strncat()
strncmp()   

相对安全


strncpy() - 字符串拷贝函数-可控制拷贝的字符个数

image.png count:要拷贝的字符的个数

如果要拷贝的字符串长度小于count,则拷贝完源字符串之后,在目标的后面追加\0,直到num个

int main()
{
    char arr1[20] = "Lemon-";
    char arr2[] = "Mango";
    strncpy(arr1, arr2, 5);
    printf("%s\n", arr1);   //Mango-
    return 0;
}

int main()
{
    char arr1[20] = "Lemon-";
    char arr2[] = "Mango";
    strncpy(arr1, arr2, 8);
    printf("%s\n", arr1);//Mango
    return 0;
}

当要拷贝的字节数大于源字符串时:超出字节数的补\0

image.png


image.png


模拟实现strncpy()

思路:比strcpy() 多一个参数count,要拷贝的字节个数,通过循环控制拷贝次数,当要拷贝的字节数大于源字符串长度时,在目标空间的后面往后补\0

char* my_strncpy(char* dest,char* src,size_t count)
{
    assert(dest&&src);
    char* ret = dest;   //保存起始空间地址
    while ( (count>0) &&(*src!='\0'))
    {
        *dest++ = *src++;
        count--;
    }
    //判断count是否还大于0,如果还大于0,说明要拷贝的字符个数比源字符串长度大->目标空间往后继续补\0
    if (count > 0)
    {
        while (count--)
        {
            *dest++ = '\0';
        }
    }
​
    return ret;
}

简化:

char* my_strncpy(char* dest,char* src,size_t count)
{
    assert(dest&& src);
    char* tmp = dest;
    while(count-- && (*dest++ = *src++))
    {
        ;
    }
    if(count > 0)
    {
        while(count>0)
        {
            count--;
            *dest++ = '\0';
        }
    }
    return tmp;
}

strncat() - 字符串追加函数

image.png

  • 第一个参数:目的地
  • 第二个参数:要追加的字符串
  • 第三个参数:要拷贝的字符个数

int main()
{
    char arr1[20] = "Mango";
    char arr2[] = "Lemon";
    strncat(arr1, arr2, 3);
    printf("%s\n", arr1);   //MangoLem
}

int main()
{
    char arr1[20] = "Mango";
    char arr2[] = "Lemon";
    strncat(arr1, arr2, 8);
    printf("%s\n", arr1);   //MangoLemon
}

当要追加的长度大于(小于)源字符串长度时,追加至源字符串\0位置即停止追加,追加结束后放入\0

int main()
{
    char arr1[20] = "Mangoxxx";
    char arr2[] = "L\0emon";
    strncat(arr1, arr2, 3);
    printf("%s\n", arr1);//MangoL
}
//虽然追加3个字符,但是arr2提前遇到\0,提前终止了

从目标空间的\0位置开始追加,追加完后自动放上\0

image.png


追加后:只追加3个,追加结束后放入\0

image.png

image.png


模拟实现strncat

思路: 1.找到目标空间的\0位置

2.进行拷贝,共拷贝n次,(注意:拷贝过程中,有可能源字符串提前遇到\0,或者要拷贝的长度比源字符串长度长

3.进行判断count是否还>0,如果还>0,说明提前遇到\0,或者源字符串长度比要拷贝的长度短。这样的话,在目标空间追加完的下一个位置补\0

char* my_strncat(char* dest, char* src, size_t count)
{
    assert(dest && src);
    char* tmp = dest;
    //1.找到目标空间\0位置
    while (*dest!='\0')
    {
        dest++;
    }
    //跳出时,dest指向的就是\0,从此处开始拷贝
    while (count-- && (*dest++ = *src++))
    {
        ;
    }
    //追加结束后,补\0
     //上面while拷贝完后,dest指向的是追加完成后的下一个位置,在此位置补\0
        *dest = '\0';
    return tmp;
}
int main()
{
    char arr1[20] = "Mango\0xxxxxx";
    char arr2[] = "Lemon";
    my_strncat(arr1, arr2, 2);
    printf("%s\n", arr1);
}