字符串函数(一):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

相关文章

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

Java中ArrayList的8种浅拷贝方式示例代码

《Java中ArrayList的8种浅拷贝方式示例代码》:本文主要介绍Java中ArrayList的8种浅拷贝方式的相关资料,讲解了Java中ArrayList的浅拷贝概念,并详细分享了八种实现浅... 目录引言什么是浅拷贝?ArrayList 浅拷贝的重要性方法一:使用构造函数方法二:使用 addAll(

C#中字符串分割的多种方式

《C#中字符串分割的多种方式》在C#编程语言中,字符串处理是日常开发中不可或缺的一部分,字符串分割是处理文本数据时常用的操作,它允许我们将一个长字符串分解成多个子字符串,本文给大家介绍了C#中字符串分... 目录1. 使用 string.Split2. 使用正则表达式 (Regex.Split)3. 使用

Java中JSON字符串反序列化(动态泛型)

《Java中JSON字符串反序列化(动态泛型)》文章讨论了在定时任务中使用反射调用目标对象时处理动态参数的问题,通过将方法参数存储为JSON字符串并进行反序列化,可以实现动态调用,然而,这种方式容易导... 需求:定时任务扫描,反射调用目标对象,但是,方法的传参不是固定的。方案一:将方法参数存成jsON字

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

百度/小米/滴滴/京东,中台架构比较

小米中台建设实践 01 小米的三大中台建设:业务+数据+技术 业务中台--从业务说起 在中台建设中,需要规范化的服务接口、一致整合化的数据、容器化的技术组件以及弹性的基础设施。并结合业务情况,判定是否真的需要中台。 小米参考了业界优秀的案例包括移动中台、数据中台、业务中台、技术中台等,再结合其业务发展历程及业务现状,整理了中台架构的核心方法论,一是企业如何共享服务,二是如何为业务提供便利。

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数

函数式编程思想

我们经常会用到各种各样的编程思想,例如面向过程、面向对象。不过笔者在该博客简单介绍一下函数式编程思想. 如果对函数式编程思想进行概括,就是f(x) = na(x) , y=uf(x)…至于其他的编程思想,可能是y=a(x)+b(x)+c(x)…,也有可能是y=f(x)=f(x)/a + f(x)/b+f(x)/c… 面向过程的指令式编程 面向过程,简单理解就是y=a(x)+b(x)+c(x)

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数