C语言常用字符串处理函数

news2024/9/24 17:19:02

C语言中包含了很多对字符串处理的函数,要使用这些函数,

首先需要导入头文件#include <string.h>

1. strlen()  --  计算字符串长度

原型:   size_t strlen(char const *string);

 例:   char *str = "abcde";

         size_t len = strlen(str);    // 结果为5

注意:  strlen()计算的结果是字符串所占有的字节数。

 

2. 不受限制的字符串函数

2.1  strcpy()  --  字符串拷贝

原型:  char *strcpy(char *dst, char const *src); 

将src的数据拷贝到dst中,覆盖dst对应位置的数据,返回指向dst的指针

例:    char* str = "abcdef";

         char arr[10];  

         char* ret = strcpy(arr,str);   //  将str中的元素拷贝到arr中,并且覆盖其原来的元素,并                                                          且返回指向arr的指针


注意:  
1. 如果拷贝的两个字符串的内存有重叠,那么结果是未定义的,所以应该避免这种操作。
2. 将src的字符串拷贝到dst的字符串,具体操作就是,将src对应的字符拷贝到dst对应的位置,将其原来的元素进行覆盖(包括字符串结束符),这样原来字符串后面的元素就不会被访问到了(看下图)

3.  dst指针在传入的时候,必须已经有了确定的空间(数组或者动态开辟),因为我们要对dst对应的字符串进行修改,所以不能在dst的位置传入字符串常量

4.  特别注意:   在拷贝的过程中,我们应该保证dst的空间应该足够容纳下src的字符串,其大小应该至少为strlen(src)+1(+1 是因为还有一个字符串结束符),否则如果src的长度比dst的空间要大,strcpy是不会检测是否超出dst的空间的,它会将不属于dst的后面的空间的数据都替换掉。
 

 

 
str1 = "abcgdef"  str2 = abc
将str2拷贝到str1中(会发现只是将str1的值进行覆盖),前面的'\0'会使得后面的数据都不会访问到,因为字符串已经结束了。

 

2.2 strcat()  --  字符串拼接 

原型:  char *strcat(char* dst, char const* src);
将src的数据拼接在dst后面,返回指向dst的指针


例子:   char[50] message;

           strcpy(message,"Hello");

           strcat(message," World");     

           printf("%s\n",message);        // Hello World

注意:
1.    如果参数指向的两个字符串发生重叠,结果是未定义的。
2.    同样,在将src拼接到dst中的时候,我们应该确保dst剩余的空间能够放下src的数据(当然包括字符串结束符),否则会发生和strcpy一样的问题。

 

2.3  strcmp() --  字符串比较

原型:  int strcmp(char const * s1, char const* s2);
比较两个字符串的大小,相同返回0, s1<s2返回负数,s1>s2返回正数


例:    char* str1 = "abc";

        char*  str2 = "efg";

        strcmp(str1,str2);       // 返回负数

注意:

1. 小于的时候并不是返回-1,而是返回负数,因为其返回值是两个字符串的差值。同理,大      于也是一样。
2.  strcmp不会修改字符串,所以我们不需要保证空间问题,但是我们需要保证两个字符串这都必须以'\0'结束,否则,strcmp()会一直向后比较,直到遇到'\0'位置,但是,此时超出了我们拥有的空间,后面的比较已经没有意义了。

 

3. 长度受限的字符串函数 

上面介绍的函数,除了比较函数,其实都存在一个问题,函数都不检查目标字符串是否空间足够放得下源字符串,必须我们自己去保证,但是总有疏漏的时候,可能就会导致程序崩溃。

所以,又提出来了这些函数的安全版本,我们可以指定拷贝的字符的个数,进而减少相应的越界问题。

但是,这些函数的使用,并没有彻底的解决问题,只是相对上面的函数而言的这个在vs中使用这些函数,如果SDL检查开启的情况下,是无法通过编译的,因为它也不安全。(这时候需要使用vs提供的安全版本)

这些函数还有一个用处(我们之前提到过):  就是可以帮助我们操作指定字节数的字符串。  

这些函数的特点:   如果src的长度比len大,那么操作len字节的字符就结束,如果src的长度比len小,那么就值操作src对应长度的字节数。

 

3.1  strncpy()  

原型:  char * strncpy(char *dst, char const *src, size_t len); 
使用方式和strcpy类似(返回值和前两个参数),只是我们可以通过第三个参数传入拷贝字符串的字节数


例子:   char arr[10] = {0};

              strncpy(arr,"abcdef",3);    //  拷贝三个字节的字符到arr中:  abc

注意: 
1.  两个字符串的空间不能重叠。
2.  一定要注意复制完之后dst必须以'\0'结尾,否则会不是字符串了。
     所以:  当len>strlen(src)的时候,那么会将src全部拷贝到dst中,包括字符串结束符。但是,当len>=strlen(src)的时候,其只会拷贝len指定的长度到dst中,这样它的字符串结束符是不会被拷贝到dst,这时候就会出问题,就是字符串在相应的位置不会结束,会访问到后面的数据。

解决方法:  

1).  如果dst对应字符串中没有数据,那么我们可以将其都设置为'\0'。
2).  我们可以在使用strncpy的时候,多考虑一步,指定的拷贝长度能够拷贝到'\0'

3).  就是在拷贝结束之后,手动将最后一个字符设置为'\0';

3.  你会发现即使有了第三个参数的限定,其实也并不是很安全,因为我们依然需要保证第三个参数或者src的长度不能超过dst。

 

3.2 strncat() 

原型和strcat类型,只是有了第三个参数,指定拷贝字节数。 用法也是类似的。

注意: 

1.   使用strncat()函数也需要注意在拼接的时候是否src的字符串结束符也被拼接到src中了,如果没有就需要我们手动解决。(就是上面说到的)

2.   两字符串的空间依然不能重叠。

 

3.3 strncmp()

和上面两个是同理的。 

 

4. vs的安全版本 

前面说到在vs中使用上面的操作函数会出错,你要么使用vs提供的安全版本,要么将SDL检查关闭。 

那么vs的安全版本如何使用呢?

其实很简单,它只是多了一个参数,因为上面我们指定的长度len必须保证比dst的长度小,这一点还必须是我们自己来保证。也容易出错。

vs的安全版本在dst参数后,传入dst所能存放的最大字节数的字符,这样如果拷贝的长度超过最大字节数,那么他就只会拷贝到最大字节数。(其余的也同理)

例子:   其余的函数都是一样的

char arr[20];

strncpy_s(arr,20,"abcdef",5);

 

5. 基础字符串的查找 

5.1 strchr(),strrchr()查找一个字符 

 原型:   char *strchr(char const *str, int ch);  // 从正向查找对应字符,返回指向对应字符第一次出现的位置的指针,如果没找到,返回NULL。
            char *strrchr(char const *str, int ch);  // 从逆向查找对应字符,返回指向对应字符第一次出现的位置的指针(也就是在字符串中最后出现的位置),没有找到返回NULL。


例:   char* ch = strchr("abc",'a');

        printf("%c\n",*ch);                // 输出'a'

 

5.2 strpbrk()查找任何几个字符 

原型:   char* strpbrk(char const* str, char const *group);  // 函数可以查找任何一组字符第一次在字符串中出现的位置,返回指向str中第一个匹配group中任何一个字符的字符位置。 group指定的所有字符都没有找到,那么就返回NULL。

例:     char arr1[] = "abcdefg";

         char arr2[] = "kfeag";
          char *ch = strpbrk(arr1,arr2);  // 因为在指定的字符中,在str中第一个出现的是'a',所以ch为指向字符'a'的指针。

 

 5.3 strstr()查找一个子串

原型:   char *strstr(char const *s1, char const *s2);   // 这个函数在s1中查找整个s2第一次出现的起始位置,并返回一个指向该位置的指针。 如果s2没有出现在s1任何一个位置,那么就返回NULL。

注意:  如果第二个字符串是一个空字符串,那么就返回s1。

例:      char* str = strstr("abcdabc","abc");  // 返回第一次出现abc的起始位置的指针。
           char* str = strstr("abcdabc","");       // 因为s2为空串,所以返回指向s1的指针。

 

注意: 在标准库中,没有strrpbrk()和strrstr() ,当然可以自己实现。

 

 

6. 高级字符串查找 

 6.1 strspn(),strcspn()查找一个字符串前缀,可用于跳过字符串前面的空白字符

原型:  size_t strspn(char const* str, char const *group); // group字符串指定一个或者多个字符,strspn返回str起始部分匹配group中任意字符的字符数。 
 

size_t strcspn(char const* str, char const *group); // group字符串指定一个或者多个字符,strspn返回str起始部分不匹配group中任意字符的字符数。 
 

注意:  此函数是在str的起始位置去找,用下面的例子说明。


例:   

例1: 

    char buffer[] = "12,35,64,Hello,World";

    size_t count = strspn(buffer, "2310456798");
    printf("%zd\n", count);  // 输出结果为2
分析:
   
我们给定了一个字符数组buffer,然后使用strspn()函数去查找buffer从起始位置开始包含的函数第二个参数中指定的字符个数。会发现,我们此处第二个参数指定的字符为'0'-'9'。
从buffer起始位置开始找,'1','2'都是第二个字符串的字符,但是第三个字符','在第二个字符组中就没有了,所以返回的是2。(从起始位置开始和group中指定字符匹配的字符个数)

例2:也是一种用法,跳过字符串前面的空白字符。

    char buffer[] = "      12,35,64,Hello,World";

    size_t count = strspn(buffer, "\n\t\v\r\f");
    printf("%zd\n", count);   // 输出的结果就是buffer对应字符串前面的空白字符个数。


所以,我们可以将buffer+count,那么就可以找到字符串第一个非空白字符的位置了。

strcspn()的用法和strspn类似,只是strcspn返回的是从str开始位置与group中指定的字符不匹配的个数。

 

6.2 strtok()查找标记 -- 也就是根据指定的分隔符将字符串分割 

请查看:  c/c++函数: strtok() ,strtok_s() 

 

7. stderror()打印错误信息 

 请查看: strerror,perror,errno

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1701379.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《软件方法(下)》8.3.4.5和《设计模式》中用语的区别

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 8.3 建模步骤C-2 识别类的关系 8.3.4 识别关联关系 8.3.4.4 类关系再整理 有了前面的知识&#xff0c;我们需要再整理一下类的关系。用类图表示类的关系如图8-134。 图8-134 “类的…

c# 贪心算法(Greedy Algo)

贪婪是一种算法范式&#xff0c;它逐步构建解决方案&#xff0c;始终选择提供最明显和直接收益的下一个部分。贪婪算法用于解决优化问题。 如果问题具有以下属性&#xff0c;则可以使用贪心法解决优化问题&#xff1a; 每一步&#xff0c;我们都可以做出当前看来最好的选择&…

Spring Cloud Alibaba 架构-Sentinel熔断降级

Sentinel主要功能 Sentinel 是阿里巴巴开源的一款流量控制、熔断降级组件&#xff0c;它主要用于保护微服务系统。Sentinel 的主要功能包括以下几个方面&#xff1a; 1. 流量控制&#xff08;Flow Control&#xff09;&#xff1a; Sentinel 通过控制并发请求的数量或速率&am…

【Python】搭建pypi私仓

1. 下载依赖 pip install pypiserver # 命令安装 pypiserver 库 pip install passlib # passlib 包来读取 Apache htpasswd 文件apt-get install -y apache2-utils2. 生成密码 使用htpasswd库在指定路径/path/to/.pypipasswd生成密码文件 htpasswd -c /path/to/.pypipasswd …

Windows64位操作系统安装汇编语言环境

1、下载好MASM工具, 并存放在指定路径 2、再安装一个DOSBox 3、打开DOSBox, 并使用 mount 将刚刚存放MASM的路径挂在到C盘&#xff0c;然后进入C盘就可以使用 MASM的命令工具了。 例如&#xff1a; mount c G:\install\study\MASM C:但是DOSBox默认打开的窗口是很小的&…

Jenkins配置(插件/角色/凭证)

目录 传送门前言一、Jenkins插件管理1、更换为国内下载源2、中文汉化插件下载&#xff08;不推荐&#xff09;3、低版本Jenkins爆红插件安装4、低版本Jenkins插件持续报错解决办法 二、Jenkins用户角色三、Jenkins凭证管理&#xff08;svn/git&#xff09;1、Username with pas…

Linux的nload/nettraf命令实时网卡流量监测

对于linux的网卡上下行流量监测方法有很多 例如nload 现成的nload命令 现成的有 nload 安装 yum -y install nload 查看所有网卡实时网速 sudo nload -m 按enter/上下翻页键即可切换网卡 查看指定网卡实时网速 sudo nload eth0 -m 基于nettraf编译的rpm包 当然也可以你…

Java计算日期相差天数的几种方法

Java计算日期相差天数的几种方法 &#x1f5d3;️ Java计算日期相差天数的几种方法摘要引言一、使用java.util.Date和java.util.Calendar&#x1f4c5;1. 使用java.util.Date示例代码 2. 使用java.util.Calendar示例代码 二、使用java.time.LocalDate&#x1f4c6;示例代码 三、…

这13个前端库,帮我在工作中赢得了不少摸鱼时间

前言 平时开发的过程中&#xff0c;常常会使用到一些第三方库来提高开发效率&#xff0c;我总结了自己工作这么久以来经常用到的 13 个库&#xff0c;希望对大家有帮助&#xff5e; antd 全称应该是Ant Design&#xff0c;这是一个 React 的组件库&#xff0c;旨在提供一套常…

基于springboot实现中国陕西民俗网系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现中国陕西民俗网系统演示 摘要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c…

内网安全--域渗透准备知识

目录 知识点&#xff1a; 0x01 0x02 0x03 系列点&#xff1a; Linux主机信息收集 windows主机信息收集 知识点&#xff1a; 0、域产生原因 1、内网域的区别 2、如何判断在域内 3、域内常见信息收集 4、域内自动化工具收集 -局域网&工作组&域环境区别 -域…

第一节:Redis的数据类型和基本操作

最近整理了关于Redis的一些文档&#xff0c;分享给大家&#xff0c;后续会持续更新...... Redis的数据类型 字符串String String&#xff1a;字符串&#xff0c;可以存储String、Integer、Float型的数据&#xff0c;甚至是二进制数据&#xff0c;一个字符串最大容量是512M 列表…

我理解的“财富真相”……

我理解的“财富真相” 人生富贵一途&#xff0c;年轻时会认为钱特别重要&#xff0c;因为要啥没啥&#xff0c;所以整台好车&#xff0c;或有个安乐窝基本是极限目标理解&#xff0c;其实也想有更多钱&#xff0c;但往远了说就具体目标模糊了&#xff0c;咬牙切齿的谈理想&…

618购物节值得入手哪些数码?值得入手的宝藏数码好物安利!

随着618购物节的到来&#xff0c;数码爱好者们纷纷摩拳擦掌&#xff0c;期待在这个年中大促中寻觅到心仪的数码好物&#xff0c;那么在这个618购物节&#xff0c;有哪些数码产品值得我们入手呢&#xff1f;接下来&#xff0c;就让我们一起盘点那些值得入手的宝藏数码好物吧&…

靠AI创意,变现20w!

文章首发于公众号&#xff1a;X小鹿AI副业 大家好&#xff0c;我是程序员X小鹿&#xff0c;前互联网大厂程序员&#xff0c;自由职业2年&#xff0c;也一名 AIGC 爱好者&#xff0c;持续分享更多前沿的「AI 工具」和「AI副业玩法」&#xff0c;欢迎一起交流~ 之前X小鹿一直在各…

注册表Windows兼容性设置(AppCompatFlags)

属性 - 兼容性 EXE文件属性中有兼容性标签&#xff0c;当有些老版本软件不能正常运行时经常会调整这里的设置。 image.png 上面的所有选项都写在注册表中&#xff0c;其中“更改所有用户的设置”保存在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AppC…

一步步实现知乎热榜采集:Scala与Sttp库的应用

背景 在大数据时代&#xff0c;网络爬虫技术发挥着不可或缺的作用。它不仅能够帮助我们快速地获取互联网上的信息&#xff0c;还能处理和分析这些数据&#xff0c;为我们提供深刻的洞察。知乎&#xff0c;作为中国领先的问答社区&#xff0c;汇聚了各行各业的专家和广大用户的…

Selenium探险家:驾驭Web自动化的秘籍与实战

Hi&#xff0c;我是阿佑&#xff0c;今天将带大伙们学会如何使用Selenium进行高效的网站测试&#xff0c;如何配置Selenium Grid实现分布式测试&#xff0c;以及如何预测和拥抱自动化测试的未来&#xff01; 文章目录 1. 引言2. 背景介绍2.1 Selenium概览2.2 Python与Selenium的…

力扣刷题--268. 丢失的数字【简单】

题目描述&#x1f357; 给定一个包含 [0, n] 中 n 个数的数组 nums &#xff0c;找出 [0, n] 这个范围内没有出现在数组中的那个数。 示例 1&#xff1a; 输入&#xff1a;nums [3,0,1] 输出&#xff1a;2 解释&#xff1a;n 3&#xff0c;因为有 3 个数字&#xff0c;所以…

YOLOv5 | 卷积模块 | 提高网络的灵活性和表征能力的动态卷积【附代码+小白可上手】

&#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 轻量级卷积神经网络由于其低计算预算限制了CNNs的深度&#xff08;卷积层数&#xff09;和宽度&#xff08;通道数&#xff09;&#xff0c;…