C语言-字符串函数

字符串

1. 字符串处理函数

1. strlen:长度

作用:测量字符串长度

语法:

size_t strlen(const char *s);

参数:

  • s:要测量的字符指针变量

返回值:

  • 字符串长度

注意:不包含 ‘\0’

  • sizeof 是个关键字,测量数据的 占用内存空间大小
    • 如果测量的是数组的名字,则测的是数组占多少个字节
    • 如果 sizeof 测的是指针变量,则测的是指针变量本身占几个字节, 32 平台下结果为 4G
  • strlen 是个库函数,它测的是字符指针指向的字符串中字符的个数,不管指针是数组的名字,还是个指针变量。

示例:

#include <stdio.h>
#include <string.h>
void fun01()
{char *str01 = "hell0";int len = strlen(str01);printf("str01的长度为:%d\n", len);
}
int main(int argc, char const *argv[])
{fun01();return 0;
}
//str01的长度为:5

2. strcpy:拷贝

语法:

char *strcpy(char *dest, const char *src);

参数:

  • dest:目标地址
  • src:要拷贝的字符串

返回值:

  • 目的内存地址

作用:拷贝 src 指向的字符串到 dest 指针指向的内存中, ’\0’ 也会拷贝

注意:

  • 必须保证 dest 指向的内存空间足够大,否则会出现内存污染
  • 要注意 拷贝与赋值的区别

示例1:

#include <string.h>
#include <stdlib.h>void fun02()
{char *str01 = "hello world!";char *str02 = (char *)malloc(strlen(str01) + 1);if (str02 == NULL){printf("内存开辟失败");return;}strcpy(str02, str01);printf("str02=%s\n", str02);if (str02 != NULL){free(str02);str02 = NULL;}
}
int main(int argc, char const *argv[])
{fun02();return 0;
}
//str02=hello world!

示例2: 拷贝与赋值的区别

void fun03()
{char str01[] = "hello";/*将str01的地址赋值给了str02此时不管str01还是str02对其进行修改,另外一个也将被修改*/char *str02 = str01;str01[0] = 'H';printf("str02=%s\n",str02);     //str02=Hellostr02[1] = 'E';printf("str01=%s\n",str01);     //str01=HEllo
}void fun04()
{char str01[] = "hello";char *str02 = (char *)malloc(strlen(str01) + 1);/*strcpy会将str01的值拷贝一份给str02此时str01修改不会影响str02反之str02修改也不会影响str01*/strcpy(str02,str01);str01[0] = 'H';printf("str02=%s\n",str02);     //str02=hello
}

3. strncpy:拷贝前n个字节

语法:

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

参数:

  • dest:目标地址
  • src:要拷贝的字符串

返回值:

  • 目的内存 的 首地址

作用:将 src 指向的字符串前 n 个字节,拷贝到 dest 指向的内存中

注意:

  • 不拷贝 ‘\0’
  • 如果 **n 大于 src **指向的字符串中的字符个数,则在 dest 后面填充 n-strlen(src)个 ’\0’

示例:

void fun05()
{char *str01 = "hello";char *str02 = (char *)calloc(5, 1);strncpy(str02, str01, 3);printf("str02=%s\n", str02);        //str02=hel
}

示例2:

void fun06()
{int len,i,len02;char buf[100]="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";len=strlen(buf);printf("buf长度:%d\n",len);     //buf长度:38strncpy(buf,"helloworld",15);   printf("buf=%s\n",buf);         //buf=helloworldlen02=strlen(buf);printf("buf拷贝后长度:%d\n",len02); //buf拷贝后长度:10for(i=0;i<len;i++)printf("%c",buf[i]);  printf("\n");//注意:遍历后发现,a还在字符串中 helloworldaaaaaaaaaaaaaaaaaaaaaaa,只是字符串以 '\0'结尾,长度和打印没显示
}

4. strcat:追加

语法:

char *strcat(char *dest, const char *src);

参数:

  • dest:目标地址
  • src:要追加的字符串

注意:

  • 会追加 ’\0’
  • 保证 dest 指向的内存空间足够大

作用: 追加 src 字符串到 dest 指向的字符串的后面

示例:

void fun08()
{char str01[100] = "hello";char str02[] = "world";strcat(str01,str02);printf("str01=%s\n",str01);  //str01=helloworld
}

5. strncat:追加前n个字符

语法:

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

参数:

  • dest:目标地址
  • src:要追加的字符串
  • n:要追加字符的个数

注意:

  • 会追加 ’\0’
  • 如果 n 大于 src 的字符个数,则只将 src 字符串追加到 dest 指向的字符串的后面追加的时候会追加’\0’ 。

作用: 追加 src 字符串 的前n个字符 到 dest 指向的字符串的后面

示例:

void fun07()
{char str01[100] = "hello";char str02[] = "world";strncat(str01,str02, 3);printf("str01=%s\n",str01);  //str01=hellowor
}

6. strcmp:比较

语法:

int strcmp(const char *s1, const char *s2);

参数:

  • s1:要比较的字符串1
  • s2:要比较的字符串2

作用:比较 s1 和 s2 指向的字符串的大小,

  • 比较的方法:逐个字符去比较 ascII 码,一旦比较出大小返回。

返回值:

  • 返回 0 ,表示所有字符都一样
  • 返回 1 ,s1 指向的字符串大于 s2 指向的字符串
  • 返回-1 ,s1 指向的字符串小于 s2 指向的字符串
void fun10()
{char *str01 = "hello";char str02[100];strcpy(str02, str01);int num = strcmp(str01, str02);if (num == 0){printf("str01和str02相同\n");}else{printf("str01和str02不相同\n");}
}
//str01和str02相同

7. strncmp:比较前n个字符

比较 s1 和 s2 指向的字符串中的前 n 个字符

小练习示例:

int fun11()
{/*用户输入账号与密码如果账号为admin,密码为123456显示登录成功否则显示登录失败*/for(int i= 0; i < 3; i++){printf("请输入账号:\n");char uname[100];scanf("%s",uname);printf("请输入密码:\n");char pword[100];scanf("%s",pword);if (strcmp(uname,"admin") == 0 && strcmp(pword,"123456") == 0){printf("登录成功\n");return 1;}else{printf("账号密码不匹配\n");if (2 - i == 0){printf("账号已被锁定\n");}else{printf("还有%d次机会\n",(2-i));}}}return 0;
}

8. strchr:字符查找函 首次匹配

语法:

char *strchr(const char *s, int c);

参数:

  • s:字符串
  • c:要查的字符

作用:在字符指针 s 指向的字符串中,找 ascii 码为 c 的字符

注意:

首次匹配,如果说 s 指向的字符串中有多个 AScII 为 c 的字符,则找的是第 1 个字符

返回值:

  • 找到了,返回 找到字符第一次出现的地址
  • 找不到,返回 NULL。

示例:

void fun11()
{char *str01 = "hello";char *p1 = strchr(str01, 'l');if (p1 != NULL){printf("p1=%p\n", p1);  //p1=0x400f46printf("o 的下标为:%ld\n", p1 - str01); //o 的下标为:2,计算字符在字符串中的第一次出现的下标}}

9. strrchr:字符查找函 末次匹配

作用:在 s 指向的字符串中,找最后一次出现的 AScII 为 c 的字符,

返回值:末次匹配的字符的地址

示例:

void fun12()
{char *str01 = "hello";char *p1 = strrchr(str01, 'l');if (p1 != NULL){printf("p1=%p\n", p1);  //p1=0x400ff7printf("o 的下标为:%ld\n", p1 - str01); //o 的下标为:3,计算字符在字符串中的第一次出现的下标}}

10. strstr 字符串匹配 首次匹配

语法:

char *strstr(const char *haystack, const char *needle);

参数:

  • haystack:被匹配的字符串
  • needle:需要匹配的字符串

作用:在 haystack 指向的字符串中查找 needle 指向的字符串,也是首次匹配

返回值:

  • 找到了:找到的字符串的首地址
  • 没找到:返回 NULL

示例:

void fun13()
{char *str = "abcddefcde";char *p = strstr(str,"cde");printf("%ld\n",p - str);        //7
}

11. atoi/atol/atof 字符串转数字

语法:

int atoi(const char *nptr);
long atol(const char *nptr);
double atof(const char *nptr);

参数:

  • nptr:被转的字符串

作用:将 nptr 指向的字符串转换成整数、长整形、浮点型(小数默认是double)

void fun14()
{int num01 = atoi("123");printf("%d\n",num01+1);  //124long num02 = atol("1111111");printf("%ld\n",num02+1);  //1111112double f03 = atof("1.23");printf("%.2lf\n",f03+1);  //2.23
}

12. strtok 字符串切割

语法:

char *strtok(char *str, const char *delim);

参数:

  • str:被切割的字符串
  • delim:切割的字符串

返回值:

  • 切割出的字符串首地址
  • 切割失败返回NULL

作用:字符串切割,按照 delim 指向的字符串中的字符,切割 str 指向的字符串。

其实就是在 str 指向的字符串中发现了 delim 字符串中的字符,就将其变成’\0’,调用一次 strtok 只切割一次,切割一次之后,再去切割的时候 strtok 的第一个参数传 NULL,意思是接着上次切割的位置继续切 。

注意:

如果 str 字符串中出现了连续的几个 delim 中的字符,则只将第一个字符变成’\0’

示例1:

void fun15()
{char s[] = "123,,,...456##..789,,..";char *str = s;char *delim = ",.#";char *p = strtok(str,delim);printf("%s\n",p);   //123char *p1 = strtok(NULL,delim);printf("%s\n",p1);  //456char *p2 = strtok(NULL,delim);printf("%s\n",p2);  //789char *p3 = strtok(NULL,delim);printf("%p\n",p3);  //(nil)
}

示例2:优化重复代码,并将切割出来的字符串写入数组

void fun16()
{char s[] = "123,,,...456##..789,,..";char *str = s;char *d = ",.#";char *buf[3];char *p = strtok(str, d);int i = 0;while(1){buf[i] = p;i++;p = strtok(NULL, d);if (p == NULL){break;}}for (int j = 0; j < 3; j++){printf("buf[%d]=%s\n", j, buf[j]);}
}
// buf[0]=123
// buf[1]=456
// buf[2]=789

示例3:再优化

void fun17()
{char s[] = "123,,,...456##..789,,..";char *d = ",.#";char *buf[3] = {s, NULL};int i = 0;while((buf[i] = strtok(buf[i], d)) != NULL && (++i));for (int j = 0; j < 3; j++){printf("buf[%d]=%s\n", j, buf[j]);}
}
// buf[0]=123
// buf[1]=456
// buf[2]=789

2. 组包

13. sprintf:格式化输出

语法:

int sprintf(char *buf, const char *format, … );

参数:

  • buf:输出到指定的内存,首地址
  • format:输出的格式
  • 值:输出的内容

作用:将 按照 format 格式 输出到 指定的 buf内存中

示例:

void fun18()
{char *str[100];sprintf(str, "%d年%d月%d日\n", 2023, 11, 06);printf("str=%s\n", str);        //str=2023年11月6日
}

扩展使用如下:

13.1 数字转字符串
void fun19()
{char *str[100];sprintf(str, "%d", 2023);printf("str=%s\n", str);        //str=2023
}
13.2 字符串拼接
void fun20()
{//字符串拼接char *str01 = "hello";char *str02 = "world";char str[100];sprintf(str,"%s%s",str01,str02);printf("%s\n",str);     //helloworld
}

3. 解包

14. sscanf:格式化输入

语法:

int sscanf(const char *buf,const char *format, … );

参数:

  • buf:从指定的内存,首地址,读入信息
  • format:输入的格式
  • 值:输入的内容

作用:将 按照 format 格式 从 buf 指定的内存区域中读入信息

示例:

void fun21()
{char *str = "2023年11月6日 20:33:58";int y = 0;int m = 0;int d = 0;int h = 0;int min = 0;int s = 0;sscanf(str,"%d年%d月%d日 %d:%d:%d",&y,&m,&d,&h,&min,&s);printf("y=%d\n",y);printf("m=%d\n",m);printf("d=%d\n",d);printf("h=%d\n",h);printf("min=%d\n",min);printf("s=%d\n",s);
}
// y=2023
// m=11
// d=6
// h=20
// min=33
// s=58
14.1 读指定宽度的数据:%[width]s

格式化 占位符 前面可以加宽度:%2d,一般用于数字

%s 前面一般不会加宽度。

void fun22()
{char *str = "1234567890";int num = 0;char c = 0;char s[3];sscanf(str, "%2d%c%s", &num, &c, s);printf("num=%d\n", num);  //12printf("c=%c\n", c);      //3printf("s=%s\n", s);     //4567890  因为取得是首地址,所以会拿到4,没有遇到'\0',所以会直接取到结束printf("s=%c\n", *s);     //4
}
14.2 跳过数据: %*s 或 %*d
void fun23()
{//跳过前两个数据,再取两个地址char *str = "1234567890";int num = 0;sscanf(str, "%*2d%2d", &num);printf("num=%d\n", num);  //num=34
}
14.3 %[a-z] 表示匹配 a 到 z 中任意字符(贪婪性:尽可能多的匹配)
void fun24()
{//char *str = "acdeAZ123abcd";char p[100];sscanf(str, "%[a-z]", p);printf("%s\n", p);  //acde
}
14.4 %[aBc] 匹配aBc中一员,贪婪性
void fun26()
{char *str = "aaaBccBaedf";char p[100];sscanf(str,"%[aBc]",p);printf("%s\n",p);  //aaaBccBa
}
14.5 %[^aFc] 匹配非 aFc 的任意字符,贪婪性
void fun27()
{char *str = "dsssaFcvrdf";char p[100];sscanf(str,"%[^aFc]",p);printf("%s\n",p);  //dsss
}
14.6 %[^a-z]表示读取除 a-z 以外的所有字符
void fun25()
{char *str = "abcdedfA123abc";char p1[100];char p2[100];sscanf(str,"%[^a-z]",p1);printf("%s\n",p1);       //结果啥也没有,所以得先跳过前面的小写sscanf(str,"%*[a-z]%[^a-z]",p2);printf("%s\n",p2);       //A123
}
14.7 练习

使用 sscanf 两个#号之间的字符串 abc#def@ghi

void fun28()
{char buf[20];sscanf("abc#def@ghi","%*[^#]%*c%[^@]",buf);printf("%s\n",buf);     //def
}

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

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

相关文章

研习代码 day49 | 动态规划——子序列问题(回文)

一、回文子串&#xff08;连续&#xff09; 1.1 题目 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串&#xf…

解决(error) ERR Errors trying to SHUTDOWN. Check logs.问题~

该问题出现在我在使用shutdown关闭redis服务器时&#xff0c;出现该问题的原因是由于配置文件的日志文件位置未配置或者缺少日志文件 我自己出现该问题是因为缺少日志文件&#xff0c;解决步骤如下所示&#xff1a; 第一步&#xff1a;在该目录下使用touch命令创建日志文件 第…

【工具与中间件】快速构建飞书群聊机器人

文章目录 0. 前言1. 无痛入门1.1 飞书创建群聊机器人1.2 Webhook 请求示例1.3 设置安全策略 2. 实战3. 总结3.1 使用体验3.2 深入使用建议 先进团队用飞书&#xff0c;先进飞书群聊有...... 0. 前言 科技蓬勃发展的今天&#xff0c;我们可以轻松拥有属于自己/团队的机器人。日…

Ubuntu18.04 本地安装CVAT标注工具

写在前面&#xff1a; 1、如果直接clone最新版本的cvat&#xff0c;python版本最好安装3.8的&#xff0c;因为其中部分代码的语法只有高版本的python才可以支持。 2、安装完成以后本地登陆可能出现"cannot connect to cvat server"的错误&#xff0c;可以从Cannot …

制作麒麟oem镜像之通过识别终端品牌与BIOS安装不同内容

原文链接&#xff1a;麒麟oem镜像之识别终端品牌与BIOS安装不同内容 **hello&#xff0c;大家好啊&#xff01;**在个性化和定制化日益成为趋势的今天&#xff0c;操作系统的定制化安装也变得越来越重要。特别是对于企业用户来说&#xff0c;能够根据不同的硬件配置和需求&…

项目实战之RabbitMQ重试机制进行消息补偿通知

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;啥技术都喜欢捣鼓捣鼓&#xff0c;喜欢分享技术、经验、生活。 &#x1f60e;人生感悟&#xff1a;尝尽人生百味&#xff0c;方知世间冷暖。 文章目录 &#x1f31f;架构图&#x…

Python Tkinter库入门与基础

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Tkinter是Python标准库中内置的图形用户界面&#xff08;GUI&#xff09;工具包&#xff0c;提供了创建窗口、按钮、文本框等GUI元素的功能。本文将介绍Tkinter的基础知识&#xff0c;帮助大家快速入门。 安装与…

【华为OD题库-066】冠亚军排名-java

题目 2012伦敦奥运会即将到来&#xff0c;大家都非常关注奖牌榜的情况&#xff0c;现在我们假设奖牌榜的排名规则如下. 1.首先gold medal数量多的排在前面 2.其次silver medal数量多的排在前面 3.然后bronze medal数量多的排在前面 4.若以上三个条件仍无法区分名次&#xff0c;…

【OpenGauss源码学习 —— (VecToRow)算子】

VecToRow 算子 概述ExecInitVecToRow 函数功能参数步骤 ExecVecToRow 函数功能描述参数返回值执行步骤DevectorizeOneBatch 函数 ExecEndVecToRow 函数总结 声明&#xff1a;本文的部分内容参考了他人的文章。在编写过程中&#xff0c;我们尊重他人的知识产权和学术成果&#x…

低成本物联网安全芯片ACL16_S 系列,可应用物联网认证、 SIM、防抄板和设备认证等产品上

ACL16_S 芯片是针对物联网认证、 SIM、防抄板和设备认证需求推出的高安全芯片。芯片采用 32 位 ARMCortex™-M0 系列内核&#xff0c;片内集成多种安全密码模块&#xff0c;包括 RSA/ECC DES/TDES、 SHA-1/-256、 AES-128/-192/-256 等国际安全算法&#xff0c;支持真随机数发…

岳阳楼3D模型纹理贴图

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 岳阳楼&#xff0c;位于湖南省岳阳市岳阳楼区洞庭北路&#xff0c;地…

Vcenter 6.7 VCSA证书过期问题处理

1. 故障现象 2022年10月25日&#xff0c;登陆VC报错。 按照报错信息&#xff0c;结合官方文档&#xff0c;判断为STS证书过期导致。 vCenter Server Appliance (VCSA) 6.5.x, 6.7.x or vCenter Server 7.0.x 在/var/log/vmware/vpxd-svcs/vpxd-svcs.log看到类似报错: ERRO…

为什么程序员会讨厌PHP编程语言?

闲来无事&#xff0c;逛了某乎看见一篇关于PHP编程的学习指南&#xff0c;深受启发。我们都知道PHP是一种流行的爬虫语言&#xff0c;尤其在Web开发方面。太有很多有点&#xff0c;例如简单易学、支持的成许多等。但是PHP也会存在一些缺点&#xff0c;如代码可读性差&#xff0…

【Java 基础】20 多线程操作方法

文章目录 1.获取和设置线程的名字1&#xff09;获取默认名字2&#xff09;获取自定义的名字 2.判断线程是否启动3.线程的强制执行4.让线程睡一会儿5.中断线程6.守护线程7.线程的礼让 前一节我们介绍了线程的定义、创建方法、状态以及各状态间的转换。在状态转换处只是简单的说明…

Windows下Linkis1.5DSS1.1.2本地调试

1 Linkis: 参考&#xff1a; 单机部署 | Apache Linkis技术分享 | 在本地开发调试Linkis的源码 (qq.com)DataSphere Studio1.0本地调试开发指南 - 掘金 (juejin.cn) 1.1 后端编译 参考【后端编译 | Apache Linkis】】 修改linkis模块下pom.xml,将mysql.connetor.scope修改…

C语言速通笔记(41-62)

40&#xff0e;十六进制转义字符&#xff1a;\x6d才是合法的&#xff0c;前面的0不能写&#xff0c;而且 x 是小写 41&#xff0e;字符型和整型是近亲&#xff1a;两个具有很大的相似之处&#xff0c;所有的字符都有一个它对应的整形数 据的 ASCLL 的数值。如 char a 65 % …

Java Socket编程之基于UDP协议通信

1.说明 Socket&#xff08;套接字&#xff09;是计算机网络编程中用于实现网络通信的一种编程接口或抽象概念。 它提供了一种标准的接口&#xff0c;使应用程序能够通过网络与其他计算机进行通信。 Socket可以看作是应用程序与网络之间的一个通信端点&#xff0c;类似于电话中…

go-fastfds部署心得

我是windows系统安装 Docker Desktop部署 docker run --name go-fastdfs&#xff08;任意的一个名称&#xff09; --privilegedtrue -t -p 3666:8080 -v /data/fasttdfs_data:/data -e GO_FASTDFS_DIR/data sjqzhang/go-fastdfs:lastest docker run&#xff1a;该命令用于运…

揭秘数据库、数据仓库、数据湖和数据湖之家

您是否想知道数据仓库与数据库有何不同&#xff1f;什么是数据湖和数据湖屋 &#xff1f;让我们用一个假设的例子来理解这些。 Bookster.biz 是全球图书销售领域的新热点。业务蓬勃发展&#xff0c;他们需要跟踪大量数据&#xff1a;数百万本书的庞大目录&#xff0c;全球数百…

还记得当初自己为什么选择计算机?一个程序猿的自述与分享

还记得当初自己为什么选择计算机&#xff1f;一个程序猿的自述与分享 大家好&#xff0c;我是微赚淘客系统的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在我年轻的时候&#xff0c;我选择了计算机专业&#xff0c;这条路虽然曲折艰难&…