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.rhkb.cn/news/318367.html

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

相关文章

DRF版本组件源码分析

DRF版本组件源码分析 在restful规范中要去&#xff0c;后端的API中需要体现版本。 3.6.1 GET参数传递版本 from rest_framework.versioning import QueryParameterVersioning单视图应用 多视图应用 # settings.pyREST_FRAMEWORK {"VERSION_PARAM": "versi…

Android(Java)项目支持Kotlin语言开发

Android&#xff08;Java&#xff09;项目通过相关Kotlin设置后&#xff0c;允许同时使用Java语言和Kotlin语言进行开发代码的。 示例环境&#xff1a; Android Studio Giraffe | 2022.3.1 Patch 3 Java 8 Kotlin 1.9.20 设置Kotlin选项&#xff1a; 第一步&#xff1a;在项…

区块链 | IPFS:Merkle DAG(进阶版)

&#x1f98a;原文&#xff1a;Merkle DAGs: Structuring Data for the Distributed Web &#x1f98a;写在前面&#xff1a;本文属于搬运博客&#xff0c;自己留存学习。 1 Merkle DAG 当我们在计算机上表示图时&#xff0c;必须通过提供节点和边的具体表示来编码我们的数据…

笔记-PPT绘图导出高清无失真图片

问题描述&#xff1a;PPT绘图已经用了高清图&#xff08;jpg、tif格式&#xff09;&#xff0c;但论文图片还是不清晰&#xff0c;打印出来还是有点糊 以下是PPT导出高清不失真图片&#xff08;emf格式&#xff09;的具体描述。 目录 一、绘图工具二、操作步骤 一、绘图工具 …

JAVA面试题---WEB部分

网络通讯 TCP与UDP TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的、 可靠的、 基于 IP 的传输层协议。 UDP 是 User Datagram Protocol 的简称&#xff0c;中文名是用户数据报协议&#xff0c;是 OSI 参考模 型中的传输层协议&#xff0c;它是…

UE5入门学习笔记(六)——编译低版本插件

对于有些低版本的插件&#xff0c;可以通过此方法自己编译到高版本而无需等待插件作者更新 使用工具&#xff1a;如图所示 步骤1&#xff1a;打开cmd&#xff0c;并使用cd命令切换到此目录 步骤2&#xff1a;输入如下指令 RunUAT.bat BuildPlugin -Plugin“路径1” -Package“…

WPF基础应用

WPF参考原文 MVVM介绍 1.常用布局控件 1.1 布局控件 WPF&#xff08;Windows Presentation Foundation&#xff09;提供了多种布局容器来帮助开发者设计用户界面&#xff0c;以下是一些常用的布局&#xff1a; Grid: Grid是最常用的布局容器之一&#xff0c;它允许你通过定…

类和对象【四】运算符重载

文章目录 运算符重载的概念运算符重载&#xff08;函数&#xff09;返回值类型&#xff1a;任意类型函数名&#xff1a;operator已有操作符 运算符重载&#xff08;函数&#xff09;的特点和注意点3个比较特殊的运算符重载赋值运算符&#xff08;&#xff09;重载返回值类型和返…

人工智能论文:BERT和GPT, GPT-2, GPT-3 的简明对比和主要区别

在BERT的论文里面&#xff1a; 2018.10 BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding&#xff0c;BERT已经解释了BERT&#xff0c;GPT&#xff0c;ELMo的区别。 *ELMo为双向RNN&#xff0c;请忽略。 主要区别&#xff1a; BERT使用的是…

15、ESP32 Wifi

ESP32 的 WIFI 功能是模块内置的&#xff0c;通过 ESP32 的基础库调用一些函数就可以轻松使用它。 Wifi STA 模式&#xff1a; 让 ESP32 连接附近 WIFI&#xff0c;可以上网访问数据。 // 代码显示搜索连接附近指定的 WIFI // 通过 pin 按键可断开连接#include <WiFi.h>…

前端入门:HTML(css轮廓,填充,宽高)

1.CSS轮廓 注意&#xff1a; outline中&#xff0c;out-style是必须要设置的&#xff0c;格式为&#xff1a; outline-style一共有以下的几个值&#xff1a; 2.CSS填充属性 这是一个用于在一个元素的内容周围产生空间&#xff0c;也就是边框内到白框外之间的距离&#xff0c;…

基于Spring Boot的商务安全邮件收发系统设计与实现

基于Spring Boot的商务安全邮件收发系统设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 已发送效果图&#xff0c;用户可以对已发送信息…

AIGC元年大模型发展现状手册

零、AIGC大模型概览 AIGC大模型在人工智能领域取得了重大突破&#xff0c;涵盖了LLM大模型、多模态大模型、图像生成大模型以及视频生成大模型等四种类型。这些模型不仅拓宽了人工智能的应用范围&#xff0c;也提升了其处理复杂任务的能力。a.) LLM大模型通过深度学习和自然语…

第一课 自动驾驶概述

1. contents 2. 什么是无人驾驶/自动驾驶 3 智慧出行大智慧 4. 无人驾驶的发展历程

领域驱动设计(DDD)笔记(一)基本概念

文章链接 领域驱动设计&#xff08;DDD&#xff09;笔记&#xff08;一&#xff09;基本概念-CSDN博客领域驱动设计&#xff08;DDD&#xff09;笔记&#xff08;二&#xff09;代码组织原则-CSDN博客 DDD基本概念 DDD 是一种面向复杂需求的软件设计方法&#xff0c;将软件开…

C# wpf 运行时替换方法实现mvvm自动触发刷新

文章目录 前言一、如何实现&#xff1f;1、反射获取属性2、定义替换方法3、交换属性的setter方法 二、完整代码1、接口2、项目 三、使用示例1、倒计时&#xff08;1&#xff09;、继承ViewModelBase&#xff08;2&#xff09;、定义属性&#xff08;3&#xff09;、属性赋值&am…

【目标检测】DEtection TRansformer (DETR)

一、前言 论文&#xff1a; End-to-End Object Detection with Transformers 作者&#xff1a; Facebook AI 代码&#xff1a; DEtection TRansformer (DETR) 特点&#xff1a; 无proposal&#xff08;R-CNN系列&#xff09;、无anchor&#xff08;YOLO系列&#xff09;、无NM…

pycharm配置wsl开发环境(conda)

背景 在研究qanything项目的过程中&#xff0c;为了进行二次开发&#xff0c;需要在本地搭建开发环境。然后根据文档说明发现该项目并不能直接运行在windows开发环境&#xff0c;但可以运行在wsl环境中。于是我需要先创建wsl环境并配置pycharm。 wsl环境创建 WSL是“Windows Su…

EasyExcel 处理 Excel

序言 本文介绍在日常的开发中&#xff0c;如何使用 EasyExcel 高效处理 Excel。 一、EasyExcel 是什么 EasyExcel 是阿里巴巴开源的一个 Java Excel 操作类库&#xff0c;它基于 Apache POI 封装了简单易用的 API&#xff0c;使得我们能够方便地读取、写入 Excel 文件。Easy…

【讲解下如何解决一些常见的 Composer 错误】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…