字符串函数(C语言详解)

1.字符串简介

字符串是一串连续的且以\0结尾的字符

char arr[]="zhangsan";//将字符串存到数组里面
char*a="lisi";//常量字符串
char arr1[]={'z','h','a','n','g'};//字符数组

注意:

1.以第一种形式初始化字符串时,计算机会自动在字符串末尾加上\0,所以在给数组申请内存空间时,需要多申请一个字节的内存来存放\0

2.第二种形式是常量字符串,是不可以被修改

3.第三种形式是字符数组,末尾没有\0,输出时需要一个字符一个字符的输出,如果想要像字符串一样一次输出,可以在最后一个字符末尾手动加上一个\0(在确保内存空间足够的情况下),然后用%s打印

4.一个字符占用一个字节的内存空间

5.字符串也可以是中文,一个中文汉字占两个字节(GBK编码)

2.字符串函数

2.1字符串函数的头文件

#include<string.h>

2.2 strlen()函数

2.2.1strlen函数的原型(计算字符串长度)

size_t strlen ( const char * str );

strlen函数的形参是一个char类型的地址,因为我们需要防止字符串的内容被修改,所以加上

const防止内容被修饰,返回值是size_t类型,也就是无符号整形,因为字符串的个数不可能为负数

2.2.2举例说明

#include<stdio.h>
int main()
{
	char arr[] = "1234567890";
	size_t len = strlen(arr);
	printf("%zd", len);
	return 0;
}

因为strlen的返回值是size_t,所以我们用size_t len来接收返回值,当然也可以用int来接收,结果也是正确的

2.2.3模拟实现strlen()函数

模拟1(计数)

size_t my_strlen(const char* str)
{
    assert(str);//断言str是否为空指针
	size_t count = 0;
	while (*str)//因为\0的的ASCLL码为0,所以当str指向\0时,不进行循环
	{
		count++;//如果str不指向\0,那么count++,统计字符个数
		str++;//统计完一个字符,向后走一个字节
    }
	return count;
}

模拟2(递归)

size_t my_strlen1(const char* str)
{
	assert(str);
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen(str + 1);
}

模拟3(指针减指针)

size_t my_strlen(const char* str)
{
	assert(str);
	char* p = str;
	while (*str)
	{
		str++;
	}
	return str - p;
}

2.3 strcpy()函数

2.3.1strcpy函数的原型(字符串拷贝)

char * strcpy ( char * destination, const char * source );

char*destination用来接收拷贝的目标地址,const char *source用来接收源字符串地址

2.3.2 举例说明

strcpy函数在使用时,会将目标空间内容覆盖

注意:1.源字符串必须以\0结尾

           2.strcpy会将\0拷贝到目标空间

           3.确保目标空间足够大,能放下源字符串

           4.确保目标空间可修改

2.3.3模拟实现strcpy()函数

char* my_strcpy(char* dest, const char* src)
{
	char* ret = dest;//记录一下起始位置的地址
	assert(dest != NULL);
	assert(src != NULL);
	while (*dest++=*src++)//挨个赋值,如果遇到\0,将\0赋值后,条件语句为假,就退出循环
	{
		;
	}
	return ret;
}

2.4 strcat()函数

2.4.1 strcat函数的原型(字符串连接)

char * strcat ( char * destination, const char * source );

2.4.2 举例说明

int main()
{
	char arr[100] = "1234567890";
	char brr[] = "888888";
	strcat(arr,brr);
	printf("%s", arr);;
	return 0;
}

注意:1.源字符串必须以\0结尾

           2.目标字符串必须要与\0,否则没办法知道从哪里开始追加

           3.确保目标空间足够大,能放下目标字符串和源字符串

           4.确保目标空间可修改

2.4.3模拟实现strcat()函数

char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (*dest)
	{
		dest++;//循环找到\0的位置
	}
	while (*dest++ = *src++)//从\0的位置开始追加
	{
		;
	}
	return ret;
}

2.5 strcmp()函数

2.5.1strcmp函数的原型(字符串比较)

int strcmp ( const char * str1, const char * str2 );

strcmp函数是一个一个字符比较,如果str1所指向的字符大于str2所指向的字符,返回大于0的数,如果str1所指向的字符小于str2所指向的字符,返回小于0的数,如果相等,继续比较下一对字符,直到比到\0为止,如果比到\0依然相等,那么返回0(字符串长度相等的情况)

2.5.2举例说明

strcmp("abcd","abcd");//返回值为0
两段字符串相同返回0

strcmp("abc","abcd");//返回值为负数
第一个字符串的第四个字符为\0,与第二个字符串的d比较是小于的,返回一个负数

strcmp("abcd","abc");//返回值为正数
d与\0比较是大于的,返回一个正数

strcmp("abs","abcd");//返回值为正数
第一个字符串的第三个字符s与第二个字符串的c比较是大于的,返回一个正数,后面的都不用比较了

strcmp("abcd","abs");//返回值为负数
第一个字符串的第三个字符c与第二个字符串的s比较是小于的,返回一个负数,后面的都不用比较了

2.5.3模拟实现strcmp()函数

int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 != NULL);
	assert(str2 != NULL);
	while (*str1 == *str2)//如果两个字符相等,那么进入循环
	{
		if (*str1 == '\0')//如果两个字符相等并且其中一个字符为\0,那么这两个字符串都走到了结尾,所以这两个字符串相等,直接返回0
			return 0;
		str1++;
		str2++;//不等于\0就使指针指向下一个位置,然后继续比较
	}
	return *str1 - *str2;//如果两个字符不相等,那么用str1指向的字符减去str2指向的字符,也就是两个字符的ASCLL码相减的到一个整数
}

2.6 strstr()函数

2.6.1strstr函数的原型(字符串查找)

const char * strstr ( const char * str1, const char * str2 );

函数返回字符串str2在字符串str1中第⼀次出现的位置

2.6.2举例说明

int main()
{
	char arr[100] = "1234567890";
	char brr[] = "456";
	printf("%s",strstr(arr,brr) );
	return 0;
}

上面这段代码的输出结果为4567890

2.6.3模拟strstr()函数

char* my_strstr(const char* str1, const char* str2)
{
	if (!*str2)//如果str2没有字符,那么结尾为\0,\0的ASCLL码值为0,非0为真,就直接返回str1的起始地址
		return (char*)str1;
	char* cp = (char*)str1;
	char* s2;
	char* s1;
	while (*cp)
	{
		s1 = cp;//因为我们要比较一段字符,当我们找到第一个字符时,需要往后比较剩余的字符是否相同
		s2 = (char*)str2;

		while (*s1 && *s2 && !(*s1 - *s2))//如果s1和s2所指向的字符都不为\0,并且两个字符相同,那么两个字符向后走,比较其他的字符
			s1++, s2++;
		if (!*s2)//如果s2走到了\0,那么说明字符串找到了,我们就返回第一个相同字符的地址
			return cp;
		cp++;//如果没找到,就继续cp++,用后面的字符和str2的第一个字符比较
	}
	return NULL;//如果没有找到,就返回空指针
}

这个是目前最复杂的模拟实验

2.7strtok()函数

2.7.1strtok函数的原型(切分字符串)

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

使用注意:

1.sep参数指向一个字符串,定义了用作分隔符的字符集合

2.第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标

3.strtok函数找到str中的下⼀个标记,并将其用 \0 结尾,返回⼀个指向这个标记的指针。(注:
strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串⼀般都是临时拷贝的内容
并且可修改

4.strtok函数的第⼀个参数不为 NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串
中的位置

5.strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标

6.如果字符串中不存在更多的标记,则返回 NULL 指针

2.7.2举例说明

int main()
{
	char str1[] = "123.21.12@21.12";
		char str2[] = "@.";//定义被切割的节点
		char str3[100];
		char *str4 = NULL;
		strcpy(str3, str1);
		for (str4 = strtok(str3, str2); str4 != NULL; str4 = strtok(NULL, str2))
		{
			printf("%s\n", str4);
		}
	return 0;
}

2.8strncpy()函数

2.8.1strncpy函数的原型(拷贝n个字符)

char * strncpy ( char * destination, const char * source, size_t num );

num表示需要拷贝的字符数

2.8.2举例说明

int main()
{
	char arr[] = "1231231";
	char brr[] = "8888";
	strncpy(arr, brr, 4);
	printf("%s", arr);
	return 0;
}

输出结果为88881231

2.8.3模拟实现strncpy()函数

char*my_strncpy(char* dest, const char* src, size_t num)
{
	char* ret = dest;
	while (num)
	{
		*dest++ = *src++;
		num--;
	}
	return ret;
}

2.9strncat()函数

2.9.1strncat函数的原型

char * strncat ( char * destination, const char * source, size_t num );

strncat函数的形参num表示要拼接的字符个数,最后补一个\0,同样要保证目标空间足够大

2.9.2举例说明

int main()
{
	char arr[20] = "1231231";
	char brr[] = "8888";
	strncat(arr, brr, 4);
	printf("%s", arr);
	return 0;
}

输出结果为12312318888

2.9.3模拟实现strncat()函数

char* my_strncat(char* dest,const char* src, size_t x)
{
	assert(dest && src); 
	char* ret = dest;
	while (*dest)
	{
		dest++;
	}
	while (x)
	{
		*dest++ = *src++;
		x--;
	}
	return ret;
}

2.10strncmp()函数

2.10.1strncmp函数的原型

int strncmp ( const char * str1, const char * str2, size_t num );

 num表示要比较的字符个数

2.10.2举例说明

int main()
{
	char arr[20] = "1231231";
	char brr[] = "1237";
	printf("%d", strncat(arr, brr, 2));
	return 0;
}

 2.10.3模拟实现strncmp()函数

int my_strcmp(char* arr1, char* arr2,size_t x)
{
	while (*arr1 == *arr2)
	{
		if (*arr1 == '\0')
		{
			return 0;
		}
		x--;
		if (x == 0)
		{
			break;
		}
		arr1++;
		arr2++;
	}
	return *arr1 - *arr2;
}

3.字符分类函数

C语言中有一系列的函数是专门做字符分类的,也就是⼀个字符是属于什么类型的字符的。
这些函数的使用都需要包含一个头文件是 ctype.h

          函数如果参数符合下列条件,就返回非零的数
         iscntrl任何控制字符
         isspace空白字符:空格 ‘ ’,换页 ‘\f’,换行 '\n', 回车 '\r',制表符'\t',  垂直制表符 '\v'
         isdigit十进制数字0~9
         isxdigit十六进制数字,包括所有十进制数字,小写字符a~f,大写字符A~F
         islower小写字母a~z
         isupper大写字母A~Z
         isalpha字母a~z或A~Z
         isalnum字母或者数字a~z,A~Z,0~9
         ispunct标点符号,任何不属于数字或者字母的图形字符(可打印)
         isgraph任何图形字符
         isprint任何可打印字符,包括图形字符和空白字符

以上这些函数形参和返回值都类似,我们以islower为例:

int islower ( int c );

islower 是能够判断参数部分的 c 是否是小写字⺟的。
通过返回值来说明是否是小写字母,如果是小写字母就返回非0的整数,如果不是小写字母,则返回0

4.字符转换函数

C语言提供了两个字符转换函数

头文件也为ctype.h

int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写
int toupper ( int c ); //将参数传进去的小写字母转大写

使用用例

#include <stdio.h>
#include <ctype.h>
int main ()
{
int i = 0;
char str[] = "Test String.\n";
char c;
while (str[i])
{
c = str[i];
if (islower(c))
c = toupper(c);
putchar(c);
i++;
}
return 0;
}

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

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

相关文章

指针(1)

1.内存和地址 1.1 内存 生活中我们有了房间号才能够快速找到房间&#xff0c;同样&#xff0c;在计算机中CPU&#xff08;中央处理器&#xff09;在处理数据时&#xff0c;需要的数据是在内存中进行读取的&#xff0c;处理完之后又会放回内存中。 在内存空间中&#xff0c…

OJ_最长公共子序列

题干 C实现 #include <iostream> #include <stdio.h> #include <algorithm> using namespace std;int dp[1002][1002];int main() {int n,m;char s1[1001];char s2[1001];scanf("%d%d",&n,&m);scanf("%s%s",s1,s2);//dp[i][j]是…

拼多多、淘宝、抖音、小红书商家,如何轻松在1688找到靠谱货源?

无论你是做拼多多、淘宝、抖音小店、小红书或者1688运营及采购商们&#xff0c;只要想在1688上寻找靠谱货源时&#xff0c;可以按照以下几个步骤进行筛选&#xff1a; 一、明确需求 首先&#xff0c;你需要清晰地了解自己的经营方向、目标消费群体以及所需产品的具体规格、材…

可变形卷积v4 |更快更强,效果远超DCNv3

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;助力高效涨点&#xff01;&#xff01;&#xff01; 一、论文摘要 我们介绍了可变形卷积v4 (DCNv4)&#xff0c;这是一种高效的算子&#xff0c;专为广泛的视觉应用而设计。DCNv4通过两个关键增强解决了…

26.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-实现生成日志文件的功能

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;25.利用全新的通…

PTA- - -个位数统计(C语言)

Hello,好久没更新啦&#xff0c;今天给大家讲解一下PTA平台上面的“个位数统计”这道题吧~ 题目是要统计一个数字每个位上数字出现的次数。下面是一个解决方案的思路和相应的 C 语言代码&#xff1a; 思路&#xff1a; 初始化一个大小为10的数组&#xff0c;用于计数每个数字…

【LeetCode】升级打怪之路 Day 24:回溯算法的解题框架

今日题目&#xff1a; 46. 全排列51. N 皇后78. 子集 目录 LC 46. 全排列LC 51. N 皇后LC 78. 子集 【classic】1&#xff09;思路一2&#xff09;思路二 今天学习了回溯算法的解题框架&#xff1a;回溯算法解题套路框架 | labuladong 回溯算法的整体框架都是&#xff1a; re…

提高工作效率,选择SmartEDA优质电子电路设计软件

在当今快节奏的工程环境中&#xff0c;电子电路设计软件的选择至关重要。随着技术的不断发展&#xff0c;工程师们需要能够快速、精确地设计和验证各种电子电路。而SmartEDA作为一款领先的电子电路设计软件&#xff0c;为工程师们提供了提高工作效率的强大工具。 1. 提供全面的…

pandas 数据透视和逆透视

本篇介绍 pandas 数据重塑的几个有用变换。假设我们有学生语数外考试的成绩数据&#xff0c;大家常见的是这种格式&#xff1a; 如果数据放在数据库中&#xff0c;下面的格式比较符合数据库范式&#xff1a; 现在&#xff0c;任务来了。要实现由图一向图二的变换&#xff0c;传…

centos破解root密码以及如何防止他人破解root密码

目录 破解root密码 服务器重启 1.再重启页面上下选择第一个按e进入内核编辑模式 2.找到linux16开头的一行&#xff0c;光标移动到最后添加 init/bin/sh Ctrlx 保存 3.进入单用户模式 4.重新挂在根分区 5.关闭selinux 6.更新密码 passwd 7.在根分区下面创建一个隐藏文件…

移动端使用 echarts中 滚动条 dataZoom 改造为内容区域可以左右滚动

移动端使用 echarts中 滚动条 dataZoom 改造为内容区域可以左右滚动 直接上图 &#xff1a; 主要是下面这段代码&#xff1a; "dataZoom": [{"type": "inside","show": false,"xAxisIndex": [0],"zoomOnMouseWheel&…

Frostmourne - Elasticsearch源日志告警配置

简介 配置Frostmourne 接入Elasticsearch源进行日志匹配告警&#xff0c;并静默规则&#xff0c;告警消息发送到企业微信&#xff0c;告警信息使用Markdown。 部署安装教程查看&#xff1a; https://songxwn.com/frostmourne_install ELK 安装教程&#xff1a;https://songx…

Spring Boot整合canal实现数据一致性解决方案解析-部署+实战

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 1.前言 2.canal部署安装 3.Spring Boot整合canal 3.1数据库与缓存一致性问题…

golang中new和make的区别

1. 先看一个例子 package mainimport "fmt"func main() {var a *int*a 10fmt.Println(*a) }运行结果是啥呢&#xff1f; 问&#xff1a;为什么会报这个panic呢&#xff1f; 答&#xff1a;因为如果是一个引用类型&#xff0c;我们不仅要声明它&#xff0c;还要为…

若依(ruoyi-vue)后端部署windows系统 (一文搞通,从idea安装到打包部署)

一、下载idea并破解&#xff0c;防止时间久了没法打开 访问 IDEA 官网&#xff0c;下载 IDEA 2023.2.3 版本的安装包&#xff0c;下载链接如下 : https://www.jetbrains.com/idea/download/ 卸载旧版本&#xff0c;安装新版本 弹框会提示选择安装路径&#xff0c;我这里直接选择…

蜡烛图K线图采用PictureBox控件绘制是实现量化交易的第一步非python量化

用vb6.0开发的量化交易软件 VB6量化交易软件的演示视频演示如上 股票软件中的蜡烛图是非常重要的一个东西&#xff0c;这里用VB6.0自带的Picture1控件的Line方法就可以实现绘制。 关于PictureBox 中的line 用法 msdn 上的说明为如下所示 object.Line [Step] …

大模型语言系列-Agent

文章目录 前言一、Agent是什么&#xff1f;二、LLM Agent1.西部世界小镇Agent2.BabyAGI3.AutoGPT4.Voyager Agent 总结 前言 自2022年ChatGPT诞生以来&#xff0c;LLM获得了收获了大量关注和研究&#xff0c;但究其根本&#xff0c;技术还是要为应用服务&#xff0c;如何将LLM…

数据结构与算法----复习Part 15 ()

本系列是算法通关手册LeeCode的学习笔记 算法通关手册&#xff08;LeetCode&#xff09; | 算法通关手册&#xff08;LeetCode&#xff09; (itcharge.cn) 目录 一&#xff0c;二叉搜索树&#xff08;Binary Search Tree&#xff09; 二叉搜索树的查找 二叉搜索树的插入 …

自动点赞软件崛起背后的秘密!你还不知道就真的OUT了!

先来看视频 智能引流黑科技&#xff0c;ks自动点赞软件教程 在数字化的世界中&#xff0c;社交媒体已经成为了我们日常生活的一部分。点赞、评论、分享&#xff0c;这些互动方式在塑造我们的数字身份的同时&#xff0c;也推动了信息的传播。然而&#xff0c;随着自动点赞软件的…

css入门基础(二)链接伪类细节详讲

注释很详细&#xff0c;直接上代码 新增内容&#xff1a; 1.链接伪类的使用顺序规范 2.链接伪类的使用效果 3.浏览器安全策略对visited伪类造成的影响 4.visited伪类的工作原理 源码&#xff1a; index.html <!DOCTYPE html> <html lang"en"> <head&…
最新文章