字符串函数(一):strcpy(拷贝),strcat(追加),strcmp(比较),及strncpy,strncat,strncmp

本文主要是介绍字符串函数(一):strcpy(拷贝),strcat(追加),strcmp(比较),及strncpy,strncat,strncmp,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

字符串函数

  • 一.strcpy(字符串拷贝)
    • 1.函数使用
    • 2.模拟实现
  • 二.strcat(字符串追加)
    • 1.函数使用
    • 2.模拟实现
  • 三.strcmp(字符串比较)
    • 1.函数使用
    • 2.模拟实现
  • 四.strncpy
    • 1.函数使用
    • 2.模拟实现
  • 五.strncat
    • 1.函数使用
    • 2.模拟实现
  • 六.strncat
    • 1.函数使用
    • 2.模拟实现

一.strcpy(字符串拷贝)

1.函数使用

char* strcpy(char* destination, const char* source);
  • strcpy函数用于拷贝字符串,即将一个字符串中的内容拷贝到另一个字符串中(会覆盖原字符串内容)。它的参数是两个指针,第一个指针指向目标字符串的首地址,即要拷贝到什么地方。第二个指针指向来源字符串的首地址,即用什么字符串拷贝。返回值是目标字符串的首地址
#include<stdio.h>
#include<string.h>
int main()
{//char* p = NULL;//p = "zhangsan";//p是指针变量,可以赋值,将z的地址赋值给p//char name[20] = "xxxxxxxxxx";//name = "zhangsan";//err,name数组名是地址,地址是一个常量值,不能被赋值,name已经被固定死了char name1[20] = "xxxxxxxxxx";char str1[] = "zhang\0san";strcpy(name1, str1);printf("%s\n", name1);char name2[20] = "xxxxxxxxxx";char str2[] = { 'b','i','t' };strcpy(name2, str2);printf("%s\n", name2);//char* p = "abcdef";//p指向常量字符串,存放a的地址,常量字符串是不能修改的//char arr[] = "bit";//strcpy(p, arr);//err//char p[] = "abcdef";//将其放入数组中,使其变成变量可以修改//char arr[] = "bit";//strcpy(p, arr);//rightreturn 0;
}

在这里插入图片描述

  • 我们看到会将源字符串末尾的’\0’,一同拷贝到目标字符串,当源字符串末尾没有’\0’的时候,会一直向后查找,直到找到’\0’为止,停止拷贝,并将’\0’拷贝到目标字符串。

总结:

  • 源字符串必须以 ‘\0’ 结束。
  • 会将源字符串中的 ‘\0’ 拷贝到目标空间。
  • 目标空间必须足够大,以确保能存放源字符串。
  • 目标空间必须可修改。

2.模拟实现

  • 进入函数体时先定义一个指针变量保存目标空间的起始位置,便于之后返回。然后将源字符串中的字符一一赋值给目标空间,直到遇到源字符串中的’\0’,将’\0’也赋值给目标空间后结束赋值,并返回目标空间的起始位置。
#include<assert.h>
char* my_strcpy(char* destination, const char* source)
{assert(str != NULL);//断言,若str为NULL,报错,头文件assert.h//或者直接assert(destination && source);char* str = destination;//保存目标空间的起始位置while (*source != '\0')//或者直接while (*source){*destination++ = *source++;}*destination = *source;return str;
}
  • 还可以这样更加简洁一些:
#include<assert.h>
char* my_strcpy(char* destination, const char* source)
{assert(str != NULL);//断言,若str为NULL,报错,头文件assert.hchar* str = destination;while (*destination++ = *source++;){;}return str;
}

二.strcat(字符串追加)

1.函数使用

char *strcat( char* destination, const char* Source );
  • strcat函数用于追加字符串,即将一个字符串中的内容追加到另一个字符串中。它的参数是两个指针,第一个指针指向目标字符串的首地址,即要追加到什么地方。第二个指针指向来源字符串的首地址,即用什么字符串追加。返回值是目标字符串的首地址
#include<stdio.h>
#include<string.h>
int main()
{char arr1[20] = "hello ";char arr2[] = "world";strcat(arr1, "world");printf("%s\n", arr2);char arr3[20] = "hello ";char arr4[] = { 'a','b','c','d','e','f' };strcat(arr3, arr4);printf("%s\n", arr3);return 0;
}

在这里插入图片描述

  • 我们看到会将源字符串末尾的’\0’,一同追加到目标字符串,当源字符串末尾没有’\0’的时候,会一直向后查找,直到找到’\0’为止,停止追加,并将’\0’追加到目标字符串。

总结:

  • 源字符串必须以 ‘\0’ 结束。
  • 目标字符串中也得有 \0 ,否则没办法知道追加从哪里开始。
  • 目标空间必须有足够的⼤,能容纳下源字符串的内容。
  • 目标空间必须可修改。
  • 字符串不能自己给自己追加('\0’被覆盖,无终止条件,陷入死循环),这就是源字符串不能被修改的原因。

2.模拟实现

  • 进入函数体依然先定义一个指针变量用于存放目标空间的起始位置,便于之后返回。然后用循环先找到目标空间的’\0’,之后从’\0’的位置开始追加源字符串的内容,直到追加到源字符串中的’\0’为止。最后返回目标空间的起始位置。
#include<assert.h>
char* my_strcat(char* destination, const char* source)
{assert(destination && source);//断言,若str为NULL,报错,头文件assert.hchar* str = destination;//保存目标空间的起始位置//找到'\0'的位置while (*destination != '\0'){destination++;}//开始追加字符串while (*source != '\0'){*destination++ = *source++;}//添加'\0'*destination = *source;return str;
}
  • 还可以这样更加简洁一些:
#include<assert.h>
char* my_strcat(char* destination, const char* source)
{assert(destination && source);char* str = destination;while (*destination != '\0'){destination++;}while (*destination++ = *source++){;}return str;
}

三.strcmp(字符串比较)

1.函数使用

int strcmp(const char* str1,const char* str2)
  • strcmp函数用于比较两个字符串内容的函数。它的参数是两个指针,指针分别指向两个待比较字符串的首地址。它的返回值是一个整型数字。
  • 依次比较的是对应字符的ASCII值。
  • 当str1 > str2的时候返回正数。
  • 当str1 == str2的时候返回0。
  • 当str1 < str2的时候返回负数。
//错误的写法
#include<stdio.h>
int main()
{char arr1[] = "zhangsan";char arr2[] = "zhangsan";if (arr1 == arr2)printf("==\n");elseprintf("!=\n");//输出!=return 0;
}
  • 我们比较数组也许会像上面这样写,但是数组名是首元素的地址,实际上比较的是两个地址,这两个数组内容虽然一样,但它们是在栈区开辟的两个不同的空间,地址是不一样的,所以无论如何都打印不出==。
//正确的比较方法
#include<stdio.h>
#include<string.h>
int main()
{char arr1[] = "zhangsan";char arr2[] = "zhangsan";int ret = strcmp(arr1, arr2);if (ret < 0)printf("<\n");else if (ret == 0)printf("==\n");//输出==elseprintf(">\n");return 0;
}

总结:

  • 第⼀个字符串大于第⼆个字符串,则返回大于0的数字。
  • 第⼀个字符串等于第⼆个字符串,则返回0。
  • 第⼀个字符串小于第⼆个字符串,则返回⼩于0的数字。
  • 那么如何判断两个字符串? 比较两个字符串中对应位置上字符ASCII码值的大小。

2.模拟实现

  • 进入函数体直接比较起始位置的字符的大小。如果相同并且不为’\0’那么继续比较下一对字符的大小;如果相同并且为’\0’那么说明字符串比较完毕,那么直接返回0;如果不同则直接返回str1与str2中对应字符的ASCII值的差值(当str1中对应字符大于str2中的对应字符时返回正值,当str1中对应字符小于str2中的对应字符时返回负值)。
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{assert(str1 && str2);//断言,若str为NULL,报错,头文件assert.hwhile (*str1 == *str2){//遇到都为'\0'的时候,说明字符串相等返回0if (*str1 == '\0')return 0;str1++;str2++;}return (*str1 - *str2);
}

以上三种字符串函数都是长度不受限制的字符串,直到’\0’为止,那有没有长度受限制的字符串函数呢?答案是有的,以下一一为您介绍。

四.strncpy

1.函数使用

char* strncpy (char* destination, const char* source, size_t num);

strncpy的参数与strcpy相比较多出了一个参数,而这个参数就是被拷贝的字符的个数。

注意:

  1. num小于等于源字符串中的字符个数时,被拷贝的字符的个数由num决定。
  2. num大于源字符串中字符的个数时,strncpy函数将源字符串中的字符拷贝到目标空间后不够的将用’\0’填充。

例如:

#include<stdio.h>
#include<string.h>
int main()
{char arr1[20] = "xxxxxxxxxx";char arr2[20] = "xxxxxxxxxx";char arr3[] = "aaaaa";strncpy(arr1, arr3, 3);strncpy(arr2, arr3, 7);printf("%s\n", arr1);printf("%s\n", arr2);return 0;
}

arr1:“aaaxxxxxxx…”,arr2:“aaaaa\0\0xxx…”。(…表示还有10个\0)。
在这里插入图片描述

2.模拟实现

char* my_strncpy(char* destination, const char* source, size_t num)
{assert(destination && source);char* ret = destination;while (*source != '\0' && num)//找到\0停止,或num==0停止{*destination++ = *source++;num--;}while (num)//若num!=0,在后面补\0,直到num==0{*destination++ = '\0';num--;}return ret;
}

五.strncat

1.函数使用

char* strncat (char* destination, const char* source, size_t num);

strncat的参数与strcat相比较多出了一个参数,而这个参数就是被追加的字符的个数。

注意:

  1. num小于源字符串中的字符个数时,被追加的字符的个数由num决定,并在追加完后再追加一个’\0’。
  2. num大于等于源字符串中的字符个数时,将源字符串内容全部追加到目标空间便结束追加,并在追加完后再追加一个’\0’。

例如:

#include<stdio.h>
#include<string.h>
int main()
{char arr1[20] = "xxxxx\0xxxx";char arr2[20] = "xxxxx\0xxxx";char arr3[] = "aaa";strncat(arr1, arr3, 2);strncat(arr2, arr3, 5);printf("%s\n", arr1);printf("%s\n", arr2);return 0;
}

在这里插入图片描述
arr1:“xxxxxaa\0xx…”,arr2:“xxxxxaaa\0x…”。(…表示还有10个\0)。

2.模拟实现

char* my_strncat(char* destination, const char* source, size_t num)
{assert(destination && source);char* ret = destination;while (*destination != '\0')//找到\0停止{destination++;}while (*source!='\0' && num)//追加字符的两个条件{*destination++ = *source++;num--;}*destination = '\0';//在最后补上\0return ret;
}

六.strncat

1.函数使用

int strncmp ( const char * str1, const char * str2, size_t num );

strncmp的参数与strcmp相比较也多出了一个参数,而这个参数也就是需要比较的字符个数。

例如:

#include<stdio.h>
#include<string.h>
int main()
{char arr1[] = "abcdef";char arr2[] = "abc";int ret1 = strncmp(arr1, arr2, 3);int ret2 = strncmp(arr1, arr2, 4);return 0;
}
  • 当num为3时,我们比较了arr1和arr2的前3个字符,而它们前3个字符都相同,所以返回的是0;
  • 当num为4时,我们比较了arr1和arr2的前4个字符,因为字符’d’的ASCII值大于字符’\0’的ASCII值,所以返回一个正值。

2.模拟实现

int my_strncmp(const char* str1, const char* str2, size_t num)
{assert(str1 && str2);while (*str1 == *str2 && num)//保证比较前num个字符{if (*str1 == '\0')return 0;str1++;str2++;num--;}return *str1 - *str2;
}

字符串函数(一)到这就结束了,还有字符串函数(二)哦!!!!
创作不易,如果能帮到你的话能赏个三连吗?感谢啦!!!
在这里插入图片描述

这篇关于字符串函数(一):strcpy(拷贝),strcat(追加),strcmp(比较),及strncpy,strncat,strncmp的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/987141

相关文章

Kotlin 作用域函数apply、let、run、with、also使用指南

《Kotlin作用域函数apply、let、run、with、also使用指南》在Kotlin开发中,作用域函数(ScopeFunctions)是一组能让代码更简洁、更函数式的高阶函数,本文将... 目录一、引言:为什么需要作用域函数?二、作用域函China编程数详解1. apply:对象配置的 “流式构建器”最

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

python中字符串拼接的几种方法及优缺点对比详解

《python中字符串拼接的几种方法及优缺点对比详解》在Python中,字符串拼接是常见的操作,Python提供了多种方法来拼接字符串,每种方法有其优缺点和适用场景,以下是几种常见的字符串拼接方法,需... 目录1. 使用 + 运算符示例:优缺点:2. 使用&nbsjsp;join() 方法示例:优缺点:3

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

java字符串数字补齐位数详解

《java字符串数字补齐位数详解》:本文主要介绍java字符串数字补齐位数,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java字符串数字补齐位数一、使用String.format()方法二、Apache Commons Lang库方法三、Java 11+的St

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

kotlin的函数forEach示例详解

《kotlin的函数forEach示例详解》在Kotlin中,forEach是一个高阶函数,用于遍历集合中的每个元素并对其执行指定的操作,它的核心特点是简洁、函数式,适用于需要遍历集合且无需返回值的场... 目录一、基本用法1️⃣ 遍历集合2️⃣ 遍历数组3️⃣ 遍历 Map二、与 for 循环的区别三、高