C 语言笔记:字符串处理函数

一、获取字符串长度函数

头文件:#include <string.h>
函数定义:size_t strlen(const char *s);
函数功能:
测字符指针 s 指向的字符串中字符的个数,不包括’\0’ 返回值:字符串中字符个数

#include <stdio.h>
#include <string.h>int main()
{char s1[100] = "hello";printf("s1_len = %d\n", strlen(s1));printf("s1_size = %d\n", sizeof(s1));char s2[100] = "hel\0lo";printf("s2_len = %d\n", strlen(s2));printf("s2_size = %d\n", sizeof(s2));char *s3 = "hello";printf("s3_len = %d\n", strlen(s3));printf("s3_size = %d\n", sizeof(s3));return 0;
}

执行结果:

s1_len = 5
s1_size = 100
s2_len = 3
s2_size = 100
s3_len = 5
s3_size = 8

strlen() 在获取字符串长度时,遇到第一个 \0 结束,且这个 \0 不算做字符串长度中。
s3 是一个指针变量,在 64 位操作系统中占 8 字节。

二、字符串拷贝函数

头文件:#include <string.h>
函数的定义:char *strcpy(char *dest, const char *src);
函数的说明:
拷贝 src 指向的字符串到 dest 指针指向的内存中,\0 也会拷贝
函数的返回值:目的内存的地址

注意:在使用此函数的时候,必须保证 dest 指向的内存空间足够大,否则会出现内存污染。(前面比后面长)

#include <stdio.h>
#include <string.h>int main()
{char s1[32] = "hello world";char s2[32] = "abcdefg";strcpy(s1, s2);printf("s1 = %s\n", s1);int i;for(i = 0;i < 32;i++){printf("[%c] - %d\n", s1[i], s1[i]);}return 0;
}

执行结果:

s1 = abcdefg
[a] - 97
[b] - 98
[c] - 99
[d] - 100
[e] - 101
[f] - 102
[g] - 103
[] - 0
[r] - 114
[l] - 108
[d] - 100
[] - 0...[] - 0

[字符] - ASCII码值

char *strncpy(char *dest, const char *src, size_t n);
函数的说明:
将 src 指向的字符串前 n 个字节,拷贝到 dest 指向的内存中
返回值:目的内存的首地址
注意:
(1)strncpy 不拷贝 \0
(2)如果 n 大于 src 指向的字符串中的字符个数,则在 dest 后面填充 n - strlen(src)\0

三、字符串追加函数

1. strcat() 函数

头文件:#include <string.h>
函数定义:char *strcat(char *dest, const char *src);
函数功能:
strcat 函数追加 src 字符串到 dest 指向的字符串的后面。追加的时候会追加’\0’ 注意:保证 dest 指向的内存空间足够大。

#include <stdio.h>
#include <string.h>int main()
{char s1[32] = "hello world";char s2[32] = "ABCDEF";strcat(s1, s2);printf("s1 = %s\n", s1);return 0;
}

执行结果:

s1 = hello worldABCDEF

strcat() 是从 s1 的 \0 位置开始追加,直到 s2 的第一个 \0 位置复制完结束。

2. strncat() 函数

char *strncat(char *dest, const char *src, size_t n);

这个函数接受三个参数:
dest:指向目标字符串的指针,即将源字符串连接到其末尾。
src:指向源字符串的指针,即要连接到目标字符串末尾的字符串。
n:要连接的 src 字符串的最大长度。

strncat() 函数会将源字符串 src 的前 n 个字符连接到目标字符串 dest 的末尾,然后在连接后的字符串末尾添加一个 null 字符,以表示字符串的结束。连接后的字符串 dest 将会被修改,并且返回指向 dest 的指针。

strncat() 函数与 strcat() 函数的区别:
strncat() 函数允许指定要连接的 src 字符串的最大长度 n,以防止 src 字符串长度超过 dest 字符串剩余空间而导致的缓冲区溢出。

四、字符串比较函数

1. strcmp() 函数

头文件:#include <string.h>
函数原型:int strcmp(const char *str1, const char *str2);
这个函数接受两个参数:
str1:指向第一个要比较的字符串的指针。
str2:指向第二个要比较的字符串的指针。
返回值:
strcmp() 函数将会按照字典顺序(ASCII 码顺序)比较两个字符串。
如果第一个字符串 str1 按照字典顺序排在第二个字符串 str2 之前,则返回一个负整数;
如果两个字符串相等,则返回 0;
如果第一个字符串 str1 按照字典顺序排在第二个字符串 str2 之后,则返回一个正整数。

例:

#include <stdio.h>
#include <string.h>int main()
{char s1[] = "hello";char s2[] = "hella";int ret = strcmp(s1, s2);if(ret == 0){printf("s1=s2\n");}else if(ret>0){printf("s1>s2\n");}else{printf("s1<s2\n");}return 0;
}

执行结果

s1>s2

当把"hella"改成"w"后,执行结果为:

s1<s2

这是因为,strcmp() 函数是逐字符比较的,只要出现不一样的 ASCII 码值,就会返回

2. strncmp() 函数

头文件:#include <string.h>
函数原型:int strncmp(const char *str1, const char *str2, size_t n);
这个函数接受三个参数:
str1:指向第一个要比较的字符串的指针。
str2:指向第二个要比较的字符串的指针。
n:要比较的字符数量。
返回值:
strncmp() 函数将会按照字典顺序(ASCII 码顺序)比较两个字符串的前 n 个字符。
如果第一个字符串 str1 的前 n 个字符按照字典顺序排在第二个字符串 str2 的前 n 个字符之前,则返回一个负整数;
如果两个字符串的前 n 个字符相等,则返回 0;
如果第一个字符串 str1 的前 n 个字符按照字典顺序排在第二个字符串 str2 的前 n 个字符之后,则返回一个正整数。

例:

#include <stdio.h>
#include <string.h>int main()
{char s1[] = "hello";char s2[] = "hella";int ret = strncmp(s1, s2, 4);if(ret == 0){printf("s1=s2\n");}else if(ret>0){printf("s1>s2\n");}else{printf("s1<s2\n");}return 0;
}

执行结果:

s1=s2

五、字符查找函数

1. strchr() 函数

头文件:#include <string.h>
函数原型:char *strchr(const char *str, int c);
这个函数接受两个参数:
str:指向要搜索的字符串的指针。
c:要查找的字符,以 ASCII 码的形式表示。
strchr() 函数会在字符串 str 中查找字符 c 第一次出现的位置,并返回一个指向该位置的指针。
返回值:
如果在字符串 str 中找到了字符 c,则返回指向该字符的指针;
如果在字符串 str 中未找到字符 c,则返回空指针 NULL。

例:

#include <stdio.h>
#include <string.h>int main()
{char s[] = "he6llo wo6rld";char *ret = strchr(s, '6');if(ret == NULL){printf("not found\n");}else{printf("found it, pos = %d\n", ret - s);}return 0;
}

执行结果:

found it, pos = 2

2. strrchr() 函数

strrchr()用于在字符串中查找指定字符的最后一次出现的位置。
头文件:#include <string.h>
函数原型:char *strrchr(const char *str, int c);
这个函数接受两个参数:
str:指向要搜索的字符串的指针。
c:要查找的字符,以 ASCII 码的形式表示。
strrchr() 函数会在字符串 str 中从后向前查找字符 c 最后一次出现的位置,并返回一个指向该位置的指针。
返回值:
如果在字符串 str 中找到了字符 c,则返回指向该字符的指针;
如果在字符串 str 中未找到字符 c,则返回空指针 NULL。

例:

#include <stdio.h>
#include <string.h>int main()
{char s[] = "he6llo wo6rld";char *ret = strrchr(s, '6');if(ret == NULL){printf("not found\n");}else{printf("found it, pos = %d\n", ret - s);}return 0;
}

执行结果:

found it, pos = 9

六、字符串匹配函数

strstr用于在字符串中查找指定子字符串的第一次出现的位置。
头文件:#include <string.h>
函数原型:char *strstr(const char *haystack, const char *needle);
这个函数接受两个参数:
haystack:指向要搜索的主字符串的指针。
needle:指向要搜索的子字符串的指针。
strstr() 函数会在主字符串 haystack 中查找子字符串 needle 的第一次出现的位置,并返回一个指向该位置的指针。
返回值:
如果在主字符串 haystack 中找到了子字符串 needle,则返回指向该子字符串的指针;
如果在主字符串 haystack 中未找到子字符串 needle,则返回空指针 NULL。

例:

#include <stdio.h>
#include <string.h>int main()
{char s[] = "1234:5678:999:666";char *ret = strstr(s, "666");if(ret == NULL){printf("没找到\n");}else{printf("找到了,在字符串的第%d个位置\n", ret - s);}return 0;
}

执行结果:

找到了,在字符串的第14个位置

七、字符串转换数值

atoi函数把字符串转换为 int 类型
头文件:#include <stdlib.h>
函数原型:int atoi(const char *nptr);\

int num;
num=atoi(123);

则 num 的值为 123

将字符串转换为 long 用 atol(const char *nptr);
将字符串转换为 double 用 atof(const char *nptr);

例:

#include <stdio.h>
#include <stdlib.h>int main()
{char s1[] = "1949";int ret1 = atoi(s1);printf("s1 = %d\n", ret1);char s2[] = "3.1415926";double ret2 = atof(s2);printf("s2 = %lf\n", ret2);return 0;
}

执行结果:

s1 = 1949
s2 = 3.141593

八、字符串切割函数

头文件:#include <string.h>
函数原型:char *strtok(char *str, const char *delim);
这个函数接受两个参数:
str:指向要切割的字符串的指针,第一次调用时传入要切割的字符串,后续调用时传入 NULL 表示继续处理上一次剩余的字符串。
delim:包含分隔符的字符串,用来指定在哪些字符处切割字符串。切割结果不包含 delim
strtok() 函数会从字符串 str 中按照 delim 中指定的分隔符进行切割,并返回第一个标记(token)。在第一次调用时,它会返回字符串 str 中第一个标记的指针,并用 null 字符替换标记的结尾,以便后续调用时能够从上一个标记的后面继续切割。在后续的调用中,如果传入的 str 参数是 NULL,则会继续处理上一次剩余的字符串,并返回下一个标记的指针。

例:

#include <stdio.h>
#include <string.h>int main()
{char s[] = "111:222222:3333:44444444:55";char *ret;//第一次切割ret = strtok(s, ":");printf("ret = %s\n", ret);//后面所有切割,都要将NULL传入strtok的第一个参数while((ret = strtok(NULL, ":")) != NULL){printf("ret = %s\n", ret);}return 0;
}

执行结果:

ret = 111
ret = 222222
ret = 3333
ret = 44444444
ret = 55

九、格式化字符串操作函数

1. sprintf() 函数

用于将格式化的数据写入到字符串中

头文件:#include <string.h>
函数原型:int sprintf(char *str, const char *format, ...);

这个函数接受至少两个参数:
str:指向目标字符串的指针,用于存储格式化后的数据。
format:格式控制字符串,包含了格式化输出的规则,类似于 printf() 函数中的格式控制字符串。
可变参数:根据格式控制字符串中的格式化说明符,提供要格式化的数据。

2. sscanf() 函数

用于从字符串中读取格式化的数据

头文件:#include <stdio.h>\ 函数原型:int sscanf(const char *str, const char *format, …);`

这个函数接受至少两个参数:
str:指向包含要解析的字符串的指针。
format:格式控制字符串,包含了解析输入字符串的规则,类似于 scanf() 函数中的格式控制字符串。
可变参数:用于存储从字符串中解析得到的数据。

例:

#include <stdio.h>void test1()
{char str[20];int a, b, c;sprintf(str, "%d:%d:%d", 2024, 5, 1);printf("str = %s\n", str);sscanf("2024:5:1", "%d:%d:%d", &a, &b, &c);printf("a = %d, b = %d, c = %d\n", a, b, c);
}int main()
{test1();return 0;
}

执行函数:

str = 2024:5:1
a = 2024, b = 5, c = 1

sscanf()的高级用法

void test2()
{//1.跳过数据:用%*d或%*schar str1[20];sscanf("1234 5678", "%*d %s", str1);printf("%s\n", str1);//2.读取指定宽度的数据:%[width]schar str2[20];sscanf("12345678", "%4s", str2);printf("%s\n", str2);//3.支持集合操作//  %[a-z]表示匹配a到z中任意字符(尽可能多的匹配)//  %[aBc]匹配a、B、c中一员,贪婪性//  %[^aFc]匹配非a、F、c的任意字符,贪婪性//  %[^a-z]表示读取除a-z以外的所有字符char str3[20];sscanf("wr89gfhGKLw32", "%[a-z]", str3);printf("%s\n", str3);
}
int main()
{test2();return 0;
}

执行结果:

5678
1234
wr

十、const

1. 修饰全局变量,只读

只能使用不能修改
如果直接修改,那么编译直接报错
如果通过指针修改,那么程序异常结束

#include <stdio.h>//1. const修饰全局变量
const int a = 100;
void test1()
{printf("a = %d", a);a = 666;//a只读,不能赋值直接修改printf("a = %d", a);int *p = &a;*p = 888;//也不能通过指针修改printf("a = %d", a);
}
int main()
{test1();return 0;
}

2. 修饰普通局部变量

不能直接通过变量名赋值修改,因为会编译报错,但可以通过地址修改

//2. const修饰普通局部变量
void test2()
{const int b = 100;printf("b = %d\n", b);// b = 666;//不能通过赋值直接修改// printf("b = %d\n", b);int *p = &b;*p = 888;printf("b = %d\n", b);
}
int main()
{test2();return 0;
}

执行结果:

b = 100
b = 888

3. 修饰指针变量

情况1:const修饰指针变量的类型
void test3()
{int c = 100;const int *p = &c;printf("*p = %d\n", *p);c = 666;printf("*p = %d\n", *p);*p = 777;printf("*p = %d\n", *p);int d = 888;p = &d;printf("*p = %d\n", *p);
}
int main()
{test3();return 0;
}

会报错:

说明不能通过指针修改地址里面的值

情况2:const修饰指针变量

const int *p = &c;改为int *const p = &c;

会报错:

说明无法修改指针变量里保存的地址

情况3:const既修饰类型又修饰变量

const int *p = &c;改为const int *const p = &c;

会同时报情况1和情况2的错误

说明只能通过变量名修改值

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

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

相关文章

怿星科技CEO潘凯:汽车软件研发工具链 国产玩家迎「历史性机会」

「智能汽车时代&#xff0c;国内非常有机会出现类似Vector的企业。」 这是怿星科技CEO潘凯深信的事情&#xff0c;他在行业内已经深耕约18年&#xff0c;创业也已经10年有余&#xff0c;带领着一个约300人的公司&#xff0c;2024年4月与高工智能汽车见面时&#xff0c;正值公司…

vitis 2020.1 Up date XSA文件后,编译不通过

原来是可以编译通过的&#xff0c;升级XSA文件后&#xff0c;出现各种问题&#xff0c;pmufw没法编译通过 xpfw_config.h:14:10: fatal error: xparameters.h: No such file or directory Vitis 2020.2 - fatal error: xparameters.h: No such file or directory (xilinx.com)…

遇到螺纹连接过程中的软连接,怎么办?——SunTorque智能扭矩系统

智能扭矩系统-智能拧紧系统-扭矩自动控制系统-SunTorque 在螺纹连接过程中遇到软连接时&#xff0c;首先需要明确软连接的概念及其特点。软连接通常指的是在螺栓拧紧过程中&#xff0c;由于紧固件与被连接件之间的材料、表面状况或装配工艺等因素&#xff0c;导致拧紧力矩不能…

前端上传大文件

在前端实现大文件上传&#xff0c;通常涉及以下几个关键步骤和技术要点&#xff0c;以确保上传过程既高效又稳定&#xff1a; 1. 文件切片 目的&#xff1a;将大文件分割成多个小块&#xff0c;以减少单次请求的负担&#xff0c;提高上传速度&#xff0c;并且增强上传的稳定性…

如何使用cPanel的Transfers功能迁移cPanel账户

近期由于我们的原虚拟主机提供商不再支持低版本的PHP&#xff0c;我们准备将所有的cPanel账户都迁移到在Hostease购买的独立服务器中&#xff0c;新购买的独立服务器配置了cPanel&#xff0c;下面我就介绍如何使用cPanel的Transfers功能&#xff0c;将旧服务器的cPanel账户迁移…

Mybatis 源码分析

《黑马架构师_源码系列-主流框架&中间件》-- MyBatis &#xff08;讲师&#xff1a;子慕&#xff09; * 手写持久层框架-仿写mybatis * Mybatis架构设计&主要组件 * Mybatis如何完成的初始化? * Mybatis如何完成的sql解析及执行? * Mybatis如何设置的参数? * Mybat…

QT外部库:zlib

前言 新建项目&#xff1a;pro文件中新增代码 LIBS -lz 在main.cpp函数中#include "zlib.h",如果此时运行代码提示没有找到对应的函数&#xff0c;那么就qt安装目录&#xff1a;D:\C\qt5.12.7\Tools\mingw730_64\x86_64-w64-mingw32\include&#xff08;这里是博主…

Echarts之桑基图的配置,带你感受数据流动之美。

一、桑基图的作用 ECharts中的桑基图&#xff08;Sankey diagram&#xff09;是一种用于显示数据流量、能量转移、材料流动等复杂关系的图表类型。它可以反映不同节点之间的流动关系、数量、比例等信息。 桑基图可以用于展示各种复杂的关系&#xff0c;比如流程图、资源分配、…

《Decoupled Contrastive Learning for Long-Tailed Recognition》阅读笔记

论文标题 《Decoupled Contrastive Learning for Long-Tailed Recognition》 针对长尾识别的解耦对比学习 作者 Shiyu Xuan 和 Shiliang Zhang 来自北京大学计算机学院多媒体信息处理国家重点实验室 初读 摘要 监督对比损失&#xff08;Supervised Contrastive Loss, SC…

前后端分离项目中的一些疑惑

1、前后端分离项目&#xff0c;浏览器发起请求后&#xff0c;请求的是前端服务器还是后端服务器&#xff1f; 在前后端分离的项目中&#xff0c;当浏览器发起请求时&#xff0c;它首先会请求的是前端服务器。 前后端分离的工作流程大致如下&#xff1a; 用户在浏览器中输入网…

阿里巴巴Java开发规范——编程规约(4)

阿里巴巴Java开发规范——编程规约&#xff08;4&#xff09; 编程规约 &#xff08;六&#xff09;并发处理 1. 【强制】获取单例对象需要保证线程安全&#xff0c;其中的方法也要保证线程安全。 说明&#xff1a;资源驱动类、工具类、单例工厂类都需要注意。 2. 【强制】…

有没有国内个人可用的GPT平替?推荐5个AI工具

随着AI技术的快速发展&#xff0c;AI写作正成为创作的新风口。但是面对GPT-4这样的国际巨头&#xff0c;国内很多小伙伴往往望而却步&#xff0c;究其原因&#xff0c;就是它的使用门槛高&#xff0c;还有成本的考量。 不过&#xff0c;随着GPT技术的火热&#xff0c;国内也涌…

MY SQL 实验一:

一、实验目的 通过实验了解MYSQL数据库服务器的基本架构及基本的使用方法。 二、实验原理、条件 本实验采用著名的开源数据库软件MYSQL 作为实验平台。MYSQL有多种版本&#xff0c;常用的是服务器版。数据库引擎是用于存储、处理和保护数据的核心服务。MYSQL有多个数据库引擎&a…

苍穹外卖面试总结

项目介绍 我完成了一个外卖项目&#xff0c;名叫苍穹外卖&#xff0c;是跟着黑马程序员的课程来自己动手写的。 项目基本实现了外卖客户端、商家端的后端完整业务。 商家端分为员工管理、文件上传、菜品管理、分类管理、套餐管理、店铺营业状态、订单下单派送等的管理、数据…

2024数学-微积分和线性代数/本科研究生专业考试/考研/论文/重点公式考点汇总/最难公式投票

## 整体公式汇总列表 http://www.deepnlp.org/equation/category/math #### 微积分 ## 几何级数http://www.deepnlp.org/equation/arithmetic-and-geometric-progressions ## 级数收敛http://www.deepnlp.org/equation/convergence-of-series ## 二项式展开 http://www.dee…

Elasticsearch:开启高效搜索与分析的新篇章

Elasticsearch&#xff1a;开启高效搜索与分析的新篇章 文章目录 Elasticsearch&#xff1a;开启高效搜索与分析的新篇章前言一、Elasticsearch的起源与特点起源特点1、分布式架构&#xff1a;2、实时性&#xff1a;3、全文搜索&#xff1a;4、可扩展性&#xff1a;5、数据类型…

电商店铺经验分享,抖店/视频号小店统统适用(2024新版)

我是王路飞。 如果你已经开通了抖店或者视频号小店&#xff0c; 但是做了几天发现做不起来/不好做。 不要担心&#xff0c;也不要放弃。 既然已经选择了电商这条路&#xff0c;就要对项目有信心&#xff0c;对自己有信心。 我给你们分享一些我做电商的一些踩坑经验&#xf…

自主抓取IMAP流量

自主抓取IMAP流量 根据测试需求&#xff0c;需要抓取IMAP流量包&#xff0c;使用wireshark Python&#xff08;IMAP库&#xff09;实现 实现Python 代码 不废话直接上&#xff1b; 注意别用SSL&#xff0c;这个是加密无法被抓包&#xff1b;port&#xff1a;143是公开&…

深入浅出 BERT

Transformer 用于学习句子中的长距离依赖关系&#xff0c;同时执行序列到序列的建模。 它通过解决可变长度输入、并行化、梯度消失或爆炸、数据规模巨大等问题&#xff0c;比其他模型表现更好。使用的注意力机制是神经架构的一部分&#xff0c;使其能够动态突出显示输入数据的…

WMS仓储管理系统库存分类的详细讲解

在当今日益复杂和快速变化的商业环境中&#xff0c;仓库管理成为了一个企业不可或缺的关键环节。WMS仓储管理系统解决方案凭借其自动化和信息化的优势&#xff0c;为企业带来了革命性的改变&#xff0c;特别是在库存分类方面。接下来&#xff0c;我们将深入探讨WMS仓储管理系统…