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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

应用程序中的会话管理和Cookie安全指南

应用程序中的会话管理和Cookie安全指南 在现代应用程序中&#xff0c;会话管理和Cookie安全是确保用户信息和数据安全的重要组成部分。本文将详细介绍会话管理的最佳实践以及如何通过安全的Cookie设置来保护会话ID的交换。 单点登录&#xff08;SSO&#xff09;及会话管理机制…

Ubuntu24.04安装tabby-terminal-1.0.207并处理依赖

1 下载 tabby-terminal-1.0.207 地址&#xff1a; https://github.com/Eugeny/tabby/releases 点击show all 36 assets 选择 tabby-1.0.207-linux-x64.deb 并下载。 2 依赖下载 gconf2_3.2.6-3ubuntu6_amd64.deb gconf2-common_3.2.6-3ubuntu6_all.deb gconf-service_3.2.6-…

【软件设计师】网络安全

1.网络安全基础信息 网络安全的五个基本要素&#xff1a; 机密性&#xff1a;确保信息不暴露给未授权的实体或进程 完整性&#xff1a;只有得到允许的人才能修改数据&#xff0c;并且能判断出数据是否已被修改 可用性&#xff1a;得到授权的实体在需要时可以访问数据&#xff0…

视频汇聚管理安防监控平台EasyCVR程序报错“create jwtSecret del server class:0xf98b6040”的原因排查与解决

国标GB28181协议EasyCVR安防视频监控平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云存储等丰富的视频能力&#xff0c;平台支持7*24小时实时高清视频监控&#xff0c;能同时播放多路监控视频流…

整理前端新出的操作工具好用又好玩(Custom Formatter,Oxlint,Nuxt DevTools,component-party)

1.使用Custom Formatter 使vue3中的reactive object 在Chrome在console中更易理解的方式展现 启用步骤&#xff1a; 1.打开控制台&#xff0c;然后打开console设置 2.前往proferences中的Console&#xff0c;勾选Enable custom formatters选项 3.刷新页面 2.使用css Overv…

网络编程基础(一)

目录 前言 一、网络体系架构 1.1 OSI 1.2 TCP/IP协议簇体系架构 二、TCP和UDP的不同 1.TCP 2.UDP 三、网络编程基础相关概念 1.字节序 1.在计算机中有关多字节整数的存储方式&#xff0c;根据主机CPU处理数据的方式不同&#xff0c;我们将主机分为大端存储和小端存储…

(免费领源码)java#SSM#mysql第三方物流系统37852-计算机毕业设计项目选题推荐

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…

Kruskal算法求最小生成树(加边法)

一、算法逻辑 想要轻松形象理解Kruskal算法的算法逻辑&#xff0c;视频肯定比图文好。 小编看过很多求相关的教学视频&#xff0c;这里选出一个我认为最好理解的这一款安利给大家。 因为他不仅讲解细致&#xff0c;而且还配合了动画演示&#xff0c;可以说把一个抽象的东西讲…

STM32高级控制定时器(STM32F103):输入捕获模式

目录 概述 1 输入捕获模式 1.1 原理介绍 1.2 实现步骤 1.3 发生输入捕获流程 2 使用STM32Cube配置工程 2.1 软件环境 2.2 配置参数 2.3 生成项目文件 3 功能实现 3.1 PWM调制占空比函数 3.2 应用函数库 4 测试 4.1 功能框图 4.2 运行结果 源代码下载地址&#xf…

微软联手清华,AI注释让文本到图像生成更符合人类偏好

获取本文论文原文PDF&#xff0c;请在公众号【AI论文解读】留言&#xff1a;论文解读 摘要 本研究展示了利用人类偏好数据集来精细调整文本到图像生成模型的潜力&#xff0c;增强了生成图像与文本提示之间的一致性。尽管取得了进展&#xff0c;现有的人类偏好数据集要么构建成…

【网络协议】划重点啦!TCP与UDP的重点面试题!!!

1. 为什么建立TCP连接是三次握手&#xff0c;而关闭连接却是四次挥手呢&#xff1f; 这是因为服务端的 LISTEN 状态下的 SOCKET 当收到 SYN 报文的建连请求后&#xff0c;它可以把 ACK和 SYN&#xff08;ACK 起应答作用&#xff0c; 而 SYN 起同步作用&#xff09; 放在一个报文…

飞控如何连接地面站

飞控连接地面站有两种方法&#xff0c;一种是USB线&#xff0c;一种是数传。 一.USB线连接 usb连接线使用安卓手机线&#xff08;一般人都有吧&#xff0c;没有很容易买和借到&#xff09; 电脑打开地面站软件。 端口选择C OM口&#xff0c;不要选择auto&#xff0c;如果你…

详细分析 tar: xx:无法 open: 没有那个文件或目录 的解决方法

目录 1. 问题所示2. 原理分析3. 解决方法 1. 问题所示 对于此问题处理起来比较简易&#xff0c;对此放置在运维的专栏模块 在执行解压的时候出现如下问题&#xff1a; (pgm37) l228l228:~/huoyanhao/pytorch-glow-master/pytorch-glow-master$ tar -xvf celeb-tfr.tar tar: …

计算机网络路由协议之内部网关协议RIP例题与详解

互联网的路由选择协议 路由器转发表的路由协议如何得出呢&#xff1f; 使用路由算法进行&#xff0c;路由算法可以分为两类&#xff1a; 静态路由选择策略和动态路由选择策略。 静态路由选择策略&#xff1a; 非自适应路由选择&#xff0c;人工配置每一条路由。 动态路由选…

遗留和现代数据库中的向量搜索

遗留和现代数据库中的向量搜索 image1 向量数据库是一种将数据&#xff08;包括文本、图像、音频和视频&#xff09;存储为向量的数据库&#xff0c;向量是高维空间中对象或概念的数学表示。 注意&#xff1a;根据数据的复杂程度和细节&#xff0c;每个向量的维数可能差别很大&…

DOS学习-目录与文件应用操作经典案例-attrib

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一.前言 二.使用 三.案例 一.前言 DOS系统中的attrib命令是一个用于显示或更改文件&#…

【CCF CAT- 全国算法精英大赛(第二场)】训练一

目录 前言训练一A题 Mysterious Rune StringB题 TouristC题 The diameter of a rectangleD题 Card 前言 我飘了&#xff0c;全国算法精英大赛本来就是三人赛&#xff0c;但是我认为自己能一个人当三个人用&#xff0c;结果被训练赛拷打。 另外赛氪这个平台有一个严重的问题&…

Diffusion相关原理

Diffusion相关原理 1、数学&#xff1a;重参数化 &#xff08;用于高斯拟合求导&#xff09;变分推断原理 &#xff08;用于损失&#xff09; 2、生成模型系列1、AE自动编码器&#xff08;AutoEncoder&#xff09;2.VAE的模型架构模型原理数学原理AE和VAE对比 3、DDMP图像高斯加…

2024 年你应该选择哪个开源大模型?

自2017年发表的论文《Attention Is All You Need》发明了Transformer架构以来&#xff0c;自然语言处理&#xff08;NLP&#xff09;取得了巨大的进展。随着2022年11月ChatGPT的发布&#xff0c;大型语言模型&#xff08;LLM&#xff09;引起了广泛关注。 你是否想在自己的用例…

揭秘网络编程:同步与异步IO模型的实战演练

摘要 ​ 在网络编程领域&#xff0c;同步(Synchronous)、异步(Asynchronous)、阻塞(Blocking)与非阻塞(Non-blocking)IO模型是核心概念。尽管这些概念在多篇文章中被广泛讨论&#xff0c;它们的抽象性使得彻底理解并非易事。本文旨在通过具体的实验案例&#xff0c;将这些抽象…