【c语言】strcpy、strcat、strcmp、strncpy、strncat、strncmp 字符串函数的使用以及模拟实现(附图文解析)

目录

预备知识

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

strcpy

strcpy的介绍以及使用

strcpy的模拟

strcat

strcat的介绍以及使用

strcat的模拟

strcmp

strcmp的介绍以及使用

strcmp的模拟

长度受限制的字符串函数

strncpy

strncpy的介绍以及使用

strncpy的模拟

strncat

strncat的介绍以及使用

strncat的模拟

strncmp

strncmp的介绍以及使用

strncmp的模拟

最后


预备知识

在关于本文章开始之间我们要先了解一下什么是assertconst以及size_t   另外,本文章介绍的函数都要用到<string.h>

assert:

在C语言中,assert(断言)是一个宏,用于检查特定的条件是否为真。如果条件不为真,则会触发一个断言失败的错误,程序将停止运行。assert的原型为:

void assert(int expression);

其中,expression是一个需要检查的条件表达式,通常为布尔类型的表达式。如果expression为真,assert什么也不做,程序继续执行;如果expression为假,则会输出一条错误信息,并停止程序执行。

举个例子,下面的代码使用assert来确保一个函数参数不为空指针:

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

void foo(int* ptr){
    assert(ptr != NULL);
    // do something with ptr
}

int main(){
    int* ptr = NULL;
    foo(ptr);
    return 0;
}

在这个例子中,当指针ptr为NULL时,assert会检查到它的值为假,程序将会输出错误信息并停止执行。

const:

const是C语言中的关键字,用来定义一个常量。它可以用在变量或函数返回值类型前,表示该变量或函数返回值是一个常量。这意味着变量值不能被修改,函数返回值不能被修改。一旦定义为常量,变量的值就不能再被修改,这有助于程序的可维护性和可读性。

例如,以下代码定义了一个整数常量:

const int a = 10;

这意味着a的值不能被修改。如果尝试修改它的值,编译器将会报错。

const也可以用于函数参数,表示该参数是一个常量,其值不能被修改。例如:

void printNum(const int num) {
    //...
}

这个函数接受一个整数参数num,但由于num是一个常量,函数内部不能修改它的值。

总之,const是C语言中用于定义常量的关键字,可以应用于变量、函数和函数参数等地方。

size_t:

size_t是C语言中的一种数据类型,它被定义为unsigned int或unsigned long

从vs编译器中转到定义就可以看到

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

strcpy

strcpy的介绍以及使用

strcpy的介绍

source指向的 C 字符串复制到destination指向的数组中,包括终止 null 字符'\0'(并在该点处停止)。

为避免溢出,目标指向的数组的大小应足够长,以包含与source相同的 C 字符串(包括终止 null 字符),并且不应在内存中与source重叠。

返回值是destination所指向的首元素地址。

strcpy的使用

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[20] = "what";
    char arr2[20] = "hello world!";
    printf("使用strcpy前%s\n",arr2);
    strcpy(arr2, arr1);   //将arr1拷贝到arr2
    printf("使用strcpy后%s", arr2);
    return 0;
}

实现效果

监视窗口情况

使用strcpy前

使用strcpy后

图解

strcpy的模拟

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcpy(char* dest,const char* str)  //用const 保护 str所指向的对象不被修改
{
    char* ret = dest;   //先获取dest所指向的首元素地址,用于后面的返回值
    assert(dest && str);   //断言,当dest或str是空指针时发出错误
    while (*str != '\0')
    {
        *dest = *str;
        dest++;
        str++;
    }
    *dest = *str;    //将最后的str所指向的'\0'赋值给*dest
    return ret;
}

int main()
{
    char arr1[20] = "what";
    char arr2[20] = "hello world!";
    printf("使用strcpy前%s\n",arr2);
    my_strcpy(arr2, arr1);   //将arr2拷贝到arr1
    printf("使用strcpy后%s", arr2);
    return 0;
}

strcat

strcat的介绍以及使用

strcat的介绍

source字符串的副本追加到destination字符串。destination 中的终止 null 字符('\0')被 source 的第一个字符覆盖,并且 null 字符('\0')包含在由 destination 中两者的串联形成的新字符串的末尾。

destination 和 source 的来源不能重叠

返回值是destination所指向的首元素地址。

strcat的使用

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[20] = "hello ";
    char arr2[20] = "world!";
    printf("连接前%s\n", arr1);
    strcat(arr1, arr2);  //连接两个字符串
    printf("连接后%s", arr1);
    return 0;
}

实现效果

如果要实现相同的效果也可以这样写

这样写不用多定义一个字符数组arr2

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[20] = "hello ";
    printf("连接前%s\n", arr1);
    strcat(arr1, "world!");  //连接两个字符串
    printf("连接后%s", arr1);
    return 0;
}

监视窗口情况

图解

strcat的模拟

由strcat的介绍可知,strcat的返回值是destination所指向的首元素地址。

所以返回类型是char*  

#include<assert.h>
#include<stdio.h>
char* my_strcat(char* dest, const char* str)
{
    assert(dest && str);   //断言,当dest或str是空指针时发出错误
    char* ret = dest;     //获取dest所指向的首元素地址,此地址为函数返回的地址
    while (*dest != '\0')     //使dest指针变量指向'\0'
    {
        dest++;
    }
    while (*str != '\0')   //这部分与strcpy类似
    {
        *dest = *str;
        dest++;
        str++;
    }
    *dest = *str;
    return ret;
}
int main()
{
    char arr1[20] = "hello ";
    char arr2[20] = "world!";
    my_strcat(arr1, arr2);
    printf("%s", arr1);
    return 0;
}

strcmp

strcmp的介绍以及使用

strcmp的介绍

将指针str1所指向的字符串与str2所指向的字符串进行比较  (比较的是两个字符的ASCII码值)

从第一个字符开始比较,如果比较的两个字符ASCII码值相等则比较接下来的两个字符的ASCII码值,直到两个字符的ASCII码值不同或者其中一个指针指向了'\0'

strcmp的返回值

如果str1指针变量指向字符的ASCII码值小于str2指针变量指向字符的ASCII码值,返回小于0的数

如果两个字符串的内容相等,返回0

如果str1指针变量指向字符的ASCII码值大于str2指针变量指向字符的ASCII码值,返回大于0的数

strcmp的使用

#include<string.h>
#include<stdio.h>
int main()
{
    char arr1[20] = "hello world";
    char arr2[20] = "no";
    int ret = strcmp(arr1, arr2);   用ret 接收strcmp的返回值
    if (ret > 0)
    {
        printf(">");
    }
    else if (ret == 0)
    {
        printf("==");
    }
    else
    {
        printf("<");
    }
    return 0;
}

运行结果

图文解析

很显然指针变量str1与指针变量str2指向字符的ASCII码值不相等,而且str2指针变量指向'n'的

ASCII码值大于str1指针变量指向'h'的ASCII码值,所以函数返回小于0的值

strcmp的模拟

#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)  //用const保护*str1和*str2的值
{
    assert(str1 && str2); //断言,如果str1或str2是空指针就会报错
    while ((*str1 == *str2) && (*str1 != '\0'))       
    {
        str1++;
        str2++;
    }
    return *str1 - *str2;
}
int main()
{
    char arr1[20] = "hello world";
    char arr2[20] = "no";
    int ret = strcmp(arr1, arr2);
    if (ret > 0)
    {
        printf(">");
    }
    else if (ret == 0)
    {
        printf("==");
    }
    else
    {
        printf("<");
    }
    return 0;
}

长度受限制的字符串函数

strncpy

strncpy的介绍以及使用

strncpy的介绍  

source的前 num 个字符复制到destination

返回值是字符串起始位置的地址

图文解析:如果在复制 num个字符之前找到source C 字符串的末尾(由 null 字符('\0')表示),

字符串长度之后的字符填充用'\0',直到总共有 num 个字符被写入它。

strncpy的使用

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[40] = "xxxxxxxxxxxxxxxxxxxxxxx";
    char arr2[40] = "hello world!";
    printf("使用前%s\n", arr1);
    strncpy(arr1, arr2, 16);
    printf("使用后%s", arr1);
    return 0;
}

运行结果如下

监视窗口情况

strncpy的模拟

#include<stdio.h>
#include<assert.h>
char* my_strncpy(char* dest,const char* str, size_t num) //用const保护str指针变量指向的字符 
{
    char* ret = dest;   //用ret指针变量记录目标字符串起始位置
    assert(dest && str);  //断言,如果dest或str是空指针就会报错
    while (num && *str != '\0')   
    {
        *dest = *str;
        dest++;
        str++;
        num--;
    }
    if (num)             //当num大于字符串的长度就会出现这种情况
    {
        while (num)
        {
            *dest = '\0';
            dest++;
            num--;
        }
    }
    return ret;
}
int main()
{
    char arr1[40] = "xxxxxxxxxxxxxxxxxxxxxxx";
    char arr2[40] = "hello world!";
    printf("使用前%s\n", arr1);
    my_strncpy(arr1, arr2, 16);
    printf("使用后%s", arr2);
    return 0;
}

strncat

strncat的介绍以及使用

strncat的介绍

附加字符串数组到目标字符串,但加以限制

每次附加字符串的时候都会往结尾加个\0

如果num的长度大于source指针变量所指向字符串的长度,在最后的字符串末尾还是会只加一个\0

返回值是字符串起始位置的地址

strncat的使用

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[40] = "hello ";
    char arr2[40] = "world!";
    printf("使用前%s\n", arr1);
    strncat(arr1, arr2,3);
    printf("使用后%s", arr1);
    return 0;
}

运行结果如下

监视窗口情况

图解

strncat的模拟

#include<stdio.h>
#include<assert.h>
char* my_strncat(char* dest,const char* str,size_t num) //用const保护str指针变量指向的字符
{
    char* ret = dest;  //用ret指针变量记录目标字符串起始位置
    assert(dest && str);  //断言,如果dest或str是空指针就会报错
    while (*dest != '\0')  //使dest指针变量指向'\0'
    {
        dest++;
    }
    while (num && *str != '\0')
    {
        *dest = *str;
        dest++;
        str++;
        num--;
    }
    *dest = '\0';  //当num为0后或者str指针变量指向的字符为'\0'停止后加上\0
    return ret;
}


int main()
{
    char arr1[40] = "hello ";
    char arr2[40] = "world!";
    printf("使用前%s\n", arr1);
    my_strncat(arr1, arr2,3);
    printf("使用后%s", arr1);
    return 0;
}

strncmp

strncmp的介绍以及使用

strncmp的介绍

将str1指针变量所指向的字符与str2指针变量所指向的字符的ASCII码值进行比较,具体原理与strcmp一样,只是在strcmp的基础上加上了num来限制

返回值 int类型

strncmp的使用

#include<string.h>
#include<stdio.h>
int main()
{
    char arr1[40] = "xxllo ";
    char arr2[40] = "xxxld!";
    int ret = strncmp(arr1, arr2, 2);  //此时num为2
    printf("%d", ret);
    return 0;
}

在vs中的运行结果为

如果将num的2改为3

int ret = strncmp(arr1, arr2, 2) ---> int ret = strncmp(arr1, arr2, 3);

在vs中的运行结果就会变为

接下来看看监视是怎样的情况

显然字符'x'的ASCII码值会大于'l',所以最后返回值为小于0的值

strncmp的模拟

#include<stdio.h>
#include<assert.h>
int my_strncmp(const char* str1,const char* str2, size_t num) 
//用const保护str1指针变量和str2指针变量所指向的字符
{
    assert(str1 && str2);  //断言,如果dest或str是空指针就会报错
    if (num == 0)
    {
        return 0;
    }
    while (--num && *str1 == *str2 && *str1 != '\0')
    {
        str1++;
        str2++;
    }
    return *str1 - *str2;
}
int main()
{
    char arr1[40] = "xxllo ";
    char arr2[40] = "xxxld!";
    int ret = my_strncmp(arr1, arr2,3 );
    printf("%d", ret);
    return 0;
}

最后

 

本文的此截图来自cplusplus.com

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值