当前位置: 首页 > news >正文

C语言之字符串函数

 

        C语言提供了许多操作字符串的函数,这些函数都包含在<string.h>库中,今天我们就来详细讲讲这些函数。

        1、strlen()

        strlen()是库中一个计算字符串长度的函数,用来返回字符串 ' \0 '之前的字符个数,不包括 ' \0 ',注意strlen必须以' \0 '结束。

	char str[10] = "abcde";int len_str = strlen(str); // 5

        2、strcpy

        strcpy是库中一个拷贝字符串函数,将source字符串,拷贝到dest目标字符串中。拷贝规则是将' \0 '之前的字符串拷贝过去。拷贝的时候,source字符串中一定要有' \0 '。

        1、strcpy()

        strcpy是一个将source字符串全部拷贝到dest中,包含' \0 ',那么我们拷贝的时候就一定要顾及source字符串的大小和dest字符串的大小,否则会出现很糟糕的现象。

	char str1[10] = "abcde";char str2[10];strcpy(str2, str1); //此时str2中就是abcde
char str1[10] = "abcde";
char str2[15] = "hello world";
strcpy(str2, str1);//此时str2中仍是abcde

        2、strncpy() 

        由于strcpy拷贝的时候可能会出现dest数组不够大,或者并不是想将source中所有字符都拷贝过去,那么我们可以用strncpy拷贝,这个就会增加一个参数:代表拷贝过去的字符个数。

	char str1[10] = "abcdefg";char str2[20] = "hello world";strncpy(str2, str1, 3);//此时str2为"abclo world"

        由此说明,strncpy其实起到的是一个覆盖作用。 将拷贝过去的字符,覆盖原有字符串的所处位置,剩下的字符不变。

        那么就有一个问题了。如果我们默认num为要拷贝过去的字符个数。如果str1的字符数没有num大呢?那会如何拷贝?答案是剩下的用' \0 '来填补

	char str1[8] = "abcde";char str2[20] = "hello world";strncpy(str2, str1, 10);//abcde

        我们可以看到原来str2中的' d '其实还是存在的,只不过前面五个用' \0 '来填充了,打印输出以' \0 '截止,故str2中可以说只剩abcde了。

        3、strcat

        strcat是一个追加字符串函数,即在dest字符串的后面,追加source字符串。

        1、strcat()

        注意:1)source字符串必须以' \0 '结尾。        2)dest字符串必须是可修改的,即不能为字符串常量。        3)dest字符串必须足够大。        4)strcat不能自己给自己追加,有其他函数来自己给自己追加。(因为自己给自己追加的话,追加上去之后,原字符串已经变了了,那么继续追加的话,就会一直往后寻找' \0',因为原字符串正在边追加边变长,永远找不到头,直到越界。)

	char str1[8] = "abcde";char str2[40] = "hello world";strcat(str2, str1);//str2此时为:hello worldabcde

         2、strncat()

        同理,追加函数也有自己的限定字符个数的追加,同样增加参数:代表追加的字符个数。

        注意:1)追加完了,会自动在追加过去的字符末尾增加' \0 '。        2)同样,如果追加的字符个数小于num,那么不足的也会以' \0 '补齐。

	char str1[8] = "abcde";char str2[40] = "hello world";strncat(str2, str1, 3);//str2此时为:hello worldabc

        4、strcmp

        strcmp函数是用来比较两个字符串的 ”大小“,这里所谓的大小呢,指的是比较从左往右第一个不同的字符的ASCII码值。如果前者小于后者,就返回一个负值;二者相等,返回0;前者大于后者就返回一个正值。

        1、strcmp()

        从左一直比较到字符串结束,直到比较到不同的字符。

	char str1[8] = "abcde";char str2[8] = "abfgh";int ret = strcmp(str1, str2);if (ret < 0)printf("小于\n");else if (ret == 0)printf("等于\n");else{printf("大于\n");}//结果为:小于

        2、strncmp()

        增加一个参数num,表示从左往右一共比较多少个字符。(只比较这num个字符,后面的不予比较)

	char str1[8] = "abcde";char str2[8] = "abfgh";int ret = strncmp(str1, str2,2);if (ret < 0)printf("小于\n");else if (ret == 0)printf("等于\n");else{printf("大于\n");}//结果为:等于

        5、strstr()

        用于查找一个字符串中是否含有子字符串。如果存在,就返回这个子串在字符串中该子串的起始地址(即如果输出的话,就是从这个子串开始一直输出到字符串结束)。如果没有,就返回空NULL。

	char str[20] = "hello nice world";char* p1 = strstr(str, "nice");printf("%s\n", p1);//输出结果为:nice worldchar* p2 = strstr(str, "linux");printf("%s\n", p2);//输出为(NULL)

        6、memcpy

        memcpy是负责拷贝两个独立的板块。 

        memcpy是一个拷贝函数,和strcpy不同的是,memcpy只将特定位置覆盖,而其余位置不变(即不会将' \0 '也拷贝过去) 。

void* memcpy(void* destination, const void* source, size_t num);

        由此可知,memcpy使用于所有的数组,不局限于字符串。 

        第一个参数:代表需要拷贝进去的字符串;第二个参数:代表从这个字符串中选出进行拷贝;size_t num:代表需要拷贝进去的字符串大小,单位是字节。

        拷贝规则:1)函数从source的位置开始向后复制num个字节的数据到destination的内存位置。        2)这个函数在遇到' \0'不会停下,而是将num个字节数完。        3)如果source和destination有任何的重叠,拷贝结果是未定义的。(即不能自己给自己拷贝,因为拷贝后,原字符串该位置处已经改变,继续拷贝的话已经不是原来的值了)

	char str1[20] = "hello world";char str2[10] = "ccccccc";memcpy(str1, str2, 9);printf("%s", str1);//此时str1为:"ccclo world"
	char str1[20] = "hello world";char str2[10] = "ccc\0ccc";memcpy(str1, str2, 9);printf("%s", str1);//此时str1为:"ccc"

        第二个拷贝,虽然输出结果为ccc,但其实是将"ccc\0ccc"全都拷贝进去的。

        7、memmove()

        memmove负责拷贝自己的内容。自拷贝

void* memmove(void* destination, const void* source, size_t num);

         由此可知,memcpy使用于所有的数组,不局限于字符串

         第一个参数:代表需要拷贝进去的字符串;第二个参数:代表从这个字符串中选出进行拷贝;size_t num:代表需要拷贝进去的字符串大小,单位是字节。

	char str1[20] = "hello,nice,world";memcpy(str1, str1+3, 4);printf("%s", str1);//此时str1为:"lo,no,nice,world"

        即将从下标为3的字符开始的后面四个字符,拷贝到str1的起始四个字符处。

	int arr[] = { 1,2,3,4,5,6,7,8 };memmove(arr, arr + 2, sizeof(int) * 2);for (int i = 0; i < 8; i++){printf("%d ", arr[i]);//3 4 3 4 5 6 7 8}

        8、memcmp()

        memcmp是任意类型数组比较大小,与strcmp比较方法一样。 

int memcmp(const void* p1, const void* p2, size_t num);

         p1,p2表示要比较的两个数组,size_t num:表示想要比较的个数的字节大小

	int arr1[] = { 1,2,3,4,5,6,7,8 };int arr2[] = { 1,2,3,5,6 };int ret = memcmp(arr1, arr2, sizeof(int)*4);printf("%d", ret);//ret小于0

        表示一共比较4个数,4 < 5,所以ret为负值。 

         9、memset()

void* memset(void* ptr, int value, size_t num);
	char str[20] = "hello,nice,world";memset(str, 'x', 5);printf("%s", str);//结果为:"xxxxx,nice,world"

         由此可以看出,memset是将数组从ptr开始的num个元素,变为value。num为字节个数

        注意:memset一般只能对字符串进行修改,整型数组修改的话会错误。

         10、总结

        对于数组修改函数,其实还有很多,我这里列出的都是一些很常用的,掌握这些就足够了。

相关文章:

  • 竞赛保研 基于GRU的 电影评论情感分析 - python 深度学习 情感分类
  • 本地websocket服务端结合cpolar内网穿透实现公网访问
  • Unity protobuf中repeated转C#文件List只读问题
  • C语言中关于操作符的理解
  • 【大数据】NiFi 中的 Controller Service
  • 【Amazon 实验②】使用缓存策略及源请求策略,用于控制边缘缓存的行为及回源行为
  • 攻防世界——game 游戏
  • 10 本让我 2023 年「生产力」暴增 5 倍的经典书|收藏
  • 05. Springboot admin集成Actuator(一)
  • Qt之QWidget 自定义倒计时器
  • 操作系统--磁盘存储器的管理
  • Apache Tomcat httpoxy 安全漏洞 CVE-2016-5388 已亲自复现
  • linux sed命令操作大全
  • Spring IoCDI
  • Mac OS 13+,Apple Silicon,删除OBS虚拟摄像头(virtual camera),
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • Angular2开发踩坑系列-生产环境编译
  • HTTP中的ETag在移动客户端的应用
  • LeetCode29.两数相除 JavaScript
  • Mysql5.6主从复制
  • node学习系列之简单文件上传
  • quasar-framework cnodejs社区
  • react 代码优化(一) ——事件处理
  • Terraform入门 - 3. 变更基础设施
  • 动态魔术使用DBMS_SQL
  • 分享几个不错的工具
  • 配置 PM2 实现代码自动发布
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 算法-图和图算法
  • 小程序测试方案初探
  • 用mpvue开发微信小程序
  • No resource identifier found for attribute,RxJava之zip操作符
  • mysql面试题分组并合并列
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • (1)Android开发优化---------UI优化
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (推荐)叮当——中文语音对话机器人
  • (一)UDP基本编程步骤
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • (转)Google的Objective-C编码规范
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .NET delegate 委托 、 Event 事件
  • .net on S60 ---- Net60 1.1发布 支持VS2008以及新的特性
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件
  • .net反混淆脱壳工具de4dot的使用
  • .net获取当前url各种属性(文件名、参数、域名 等)的方法
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?
  • @Bean注解详解
  • @ConfigurationProperties注解对数据的自动封装