【C语言】字符串函数及其模拟实现

news2024/12/24 2:17:58

这是最好的时代,这是最坏的时代,我们一无所有,我们巍然矗立
本文由@睡觉待开机原创,未经允许不得转载。
本内容在csdn网站首发
欢迎各位点赞—评论—收藏
如果存在不足之处请评论留言,共同进步!

系列文章目录

注:由于系列文章没有完成,系列文章目录暂时欠缺。
C语言字符串函数及其模拟实现(本文章)
C语言中动态内存管理


文章目录

  • 系列文章目录
  • 前言
  • 1.字符分类函数
  • 2.字符转换函数
  • 3.strlen求字符串长度函数
    • 3.1strlen函数的使用(头文件:<string.h>)
    • 3.2strlen函数的模拟实现
  • 4.strcpy字符串拷贝函数
    • 4.1strcpy函数的使用
    • 4.2strcpy函数的模拟实现
  • 5.strcat函数
    • 5.1strcat函数的使用
    • 5.2strcat函数的模拟实现
  • 6.strcmp字符串比较函数
    • 6.1strcmp函数的使用
    • 6.2strcmp函数的模拟实现
  • 7.strncpy,strncat,strncmp函数
    • 7.1strncpy,strncat,strncmp
    • 7.2strcpy,strcat,strcmp与strncpy,strncat,strncmp的区别?
      • 7.2.1strncpy函数
      • 7.2.1strncat函数
      • 7.3strncmp函数
  • 8.strstr函数
    • 8.1strstr函数的使用
    • 8.2strstr函数的模拟实现
  • 9.strtok函数
    • 9.1strtok函数的基本语法
    • 9.2strtok函数的使用(代码)
  • 10.strerror与str
    • 10.1strerror
      • 10.1.1strerror函数的基本语法规则:
      • 10.1.2sterror函数的使用(代码):
    • 10.2perror函数
      • 10.2.1perror函数的基本语法(头文件:stdio.h)
      • 10.2.2perror函数的使用举例
  • 总结:


前言

字符是C语言中整形家族的一大特殊群体,其本质是ASCII码值进行转换的,其相关的常见库函数会在编写代码时提供一些便利,下面来简单看一下:


1.字符分类函数

字符分类函数,是对于全体字符进行分类的。
在这里插入图片描述
我们以isdigit函数语法为例,其他都是基本相同的
在这里插入图片描述

2.字符转换函数

常用的两个字符转换函数:
在这里插入图片描述

3.strlen求字符串长度函数

3.1strlen函数的使用(头文件:<string.h>)

在这里插入图片描述

#include<stdio.h>
#include<string.h>
//strlen函数返回值是size_t容易误用
int main()
{
	if (strlen("abc") - strlen("abcdef") > 0)//易错:3-6=?
		printf("surprise\n");
	else
		printf("normal\n");
	return 0;
}

3.2strlen函数的模拟实现

strlen函数实现有多种方式,下面简单介绍几种思路:
在这里插入图片描述

//strlen函数的模拟实现
size_t my_strlen1(char* str)
{
	size_t count = 0;
	while (*str++)
	{
		count++;
	}
	return count;
}
size_t my_strlen2(char* str)
{
	char* start = str;
	while (*str++)
	{
		;
	}
	return str - start - 1;
}
size_t my_strlen3(char* str)
{
	if (!*str)
	{
		return 0;
	}
	else
		return 1 + my_strlen3(++str);
}
int main()
{
	char str[] = "abcdef";
	size_t result1 = my_strlen1(str);
	size_t result2 = my_strlen2(str);
	size_t result3 = my_strlen3(str);
	printf("result of way1 = %zd\n", result1);
	printf("result of way2 = %zd\n", result2);
	printf("result of way3 = %zd\n", result3);

	return 0;
}

4.strcpy字符串拷贝函数

4.1strcpy函数的使用

功能:strcpy是将source字符串中的内容拷贝到destion中去,包括\0
在这里插入图片描述
返回值说明:如果拷贝成功,返回destion的地址;如果拷贝失败,返回NULL;

4.2strcpy函数的模拟实现

//strcpy函数的模拟实现
char* my_syrcpy(char* des, const char* src)
{
	char* start = des;
	while (*des++ = *src++)
	{
		;
	}
	return start;
}
int main()
{
	char des[100] = {0};
	char src[] = "hello the world";
	//char* result1 = strcpy(des,src);
	char* result2 = my_syrcpy(des,src);
	//printf("result of library function is: %s\n", result1);
	printf("result of custom function  is: %s\n", result2);

	return 0;
}

5.strcat函数

5.1strcat函数的使用

功能:将source中的字符串追加到destion中字符串的后面去。
在这里插入图片描述
返回值说明:如果追加成功,返回destion的地址;如果拷贝失败,返回NULL;

5.2strcat函数的模拟实现

//strcat函数的模拟实现
char* my_strcat(char* str,const char* src)
{
	char* start = str;
	while (*str++)
	{
		;
	}
	str--;
	while (*str++ = *src++)
	{
		;
	}
	return start;
}
int main()
{
	char str[100] = "hello ";
	char src[] = "the world";
	//char* result1 = strcat(str,src);
	char* result2 = my_strcat(str, src);

	//printf("result1 of library function is : %s\n", result1);
	printf("result2 of custom function is : %s\n", result2);
	return 0;
}

6.strcmp字符串比较函数

6.1strcmp函数的使用

在这里插入图片描述

6.2strcmp函数的模拟实现

//strcmp函数的模拟实现
int my_strcmp(char* str1, char* str2)
{
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
		{
			return 0;
		}
		str1++;
		str2++;
	}
	if (*str1 > *str2)
		return 1;
	else
		return -1;
}
int main()
{
	char str1[] = "abcdef";
	char str2[] = "abcq";
	int result = my_strcmp(str1,str2);
	if (result > 0)
		printf("str1 > str2\n");
	else if (result < 0)
		printf("str1 < str2\n");
	else
		printf("str1 = str2\n");
	return 0;
}

7.strncpy,strncat,strncmp函数

7.1strncpy,strncat,strncmp

strncpy,strncat,strncmp这三个函数基本与strcpy,strcat,strcmp函数语法基本是一致的,不过多了个参数,用来控制拷贝几个,追加几个,比较几个字符,相对strcpy,strcat,strcmp函数而言更加安全一些。这里不多赘述。

我们举一个例子说明这三个的基本语法:
在这里插入图片描述

7.2strcpy,strcat,strcmp与strncpy,strncat,strncmp的区别?

7.2.1strncpy函数

stencpy拷贝不会刻意加上\0,把原函数全部拷贝了如果还达不到程序员设置最大字符限制,补\0

7.2.1strncat函数

追加完字符串后,会主动追加一个\0,保证目标字符串是一个字符串。也就是说,他会追加n-1个字符还有1个’\0’。

不会超过原字符串的长度去追加。

7.3strncmp函数

这个就是限制了比较的长度而已,目前没发现什么区别。

8.strstr函数

8.1strstr函数的使用

strstr函数是干什么的?
功能:strstr函数是用来在一个字符串中找另一个字符串的第一次出现的地址的。
在这里插入图片描述
strstr函数的使用代码一览:

int main()
{
	char destion[] = "abcabbbbcd";
	char source[] = "bcd";
	char* result1 = strstr(destion, source);
	//char* result2 = my_strstr(destion, source);

	printf("the result of standard library is : %s", result1);
	//printf("the result of myself way is : %s", result2);
	return 0;
}

8.2strstr函数的模拟实现

char* my_strstr(const char* destion,const  char* source)
{
	char* cur = destion;
	char* s1 = NULL;
	char* s2 = NULL;
	//特殊情况,直接让我找个\0,我直接给他把目标字符串的地址给他返回去
	if (*source == '\0')
	{
		return destion;
	}

	while (*cur)
	{
		s1 = cur;//每次cur变化时候,把s1初始化为cur开始的地方
		s2 = source;//每次cur变化的时候,把s2初始化为source开始的地方
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return cur;
		}
		
		cur++;
	}
	return NULL;
	
}
int main()
{
	char destion[] = "abcabbbbcd";
	char source[] = "bcd";
	//char* result1 = strstr(destion, source);
	char* result2 = my_strstr(destion, source);

	//printf("the result of standard library is : %s", result1);
	printf("the result of myself way is : %s", result2);
	return 0;
}

9.strtok函数

9.1strtok函数的基本语法

首先第一个问题哈,strtok函数是干啥的?下面来揭示strtok函数的基本语法规则:
在这里插入图片描述

9.2strtok函数的使用(代码)

//strtok函数的使用
int main()
{

	char str1[] = "zhangsan/163@qq.com";
	char str2[] = "/@.";

	char* s1 = strtok(str1, str2);
	printf("%s\n", s1);

	s1 = strtok(NULL, str2);
	printf("%s\n", s1);

	s1 = strtok(NULL, str2);
	printf("%s\n", s1);

	s1 = strtok(NULL, str2);
	printf("%s\n", s1);

	return 0;
}

代码结果:
在这里插入图片描述
这样显然是可以使用strtok函数的,不过需要调用四次,是比较麻烦的,一般我们可以结合for循环进行使用:

//strtok函数结合for循环使用:
int main()
{
	char str1[] = "zhangsan/163@qq.com";
	char str2[] = "/@.";
	char* p = NULL;
	for (p = strtok(str1, str2); p != NULL; p = strtok(NULL, str2))
	{
		printf("%s\n", p);
	}
	return 0;
}

10.strerror与str

10.1strerror

10.1.1strerror函数的基本语法规则:

在这里插入图片描述

10.1.2sterror函数的使用(代码):

int main()
{
	int i = 0;
	for (i = 0; i <= 10; i++)
	{
		printf("the %d error is :%s\n",i, strerror(i));
	}
	return 0;
}

其结果为:
在这里插入图片描述

这是0到10错误码翻译对应的信息。
一般我们是这样用的:

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
	FILE* pFile;
	pFile = fopen("unexist.ent", "r");
	if (pFile == NULL)
		printf("Error opening file unexist.ent: %s\n", strerror(errno));
	return 0;
}

10.2perror函数

10.2.1perror函数的基本语法(头文件:stdio.h)

相对于strerror函数来说,更加直接
在这里插入图片描述

10.2.2perror函数的使用举例

#include <stdio.h>
#include <string.h>
#include<errno.h>
int main()
{
	FILE* pFile;
	pFile = fopen("unexist.ent", "r");
	if (pFile == NULL)
	{
		//可以放开注释对比一下
		//printf("Error opening file unexist.ent of strerror: %s\n", strerror(errno));
		perror("Error opening file unexist.ent of perror");
	}

	return 0;
}

总结:

字符串函数是我们C语言常用的针对字符串操作的函数,有利于加深对字符串的理解。
感谢您阅读本文。如果您有任何问题或需要进一步了解,请随时联系我。祝您一切顺利!

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

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

相关文章

vue3 后台返回的接口数据,下载图片到本地

vue3 后台返回的接口数据&#xff0c;下载图片到本地 <el-table><el-table-column align"left" label"操作" min-width"240"><template #default"scope"><el-button icon"edit" type"primary&quo…

记录 | vscode禁止插件自动更新的方法

shift command p 打开然后输入 > setting.json&#xff0c;选择用户设置 在 settings.json 配置文件中增加一项&#xff1a; "extensions.autoUpdate": false,

基于pandoraNext使用chatgpt4

1.登陆GitHub 获取pandoraNext项目GitHub - pandora-next/deploy: Pandora Cloud Pandora Server Shared Chat BackendAPI Proxy Chat2API Signup Free PandoraNext. New GPTs(Gizmo) UI, All in one! 在release中选择相应版本操作系统的安装包进行下载 2.获取license_…

如何成为一名初级产品经理?

自然是需要系统的学习产品经理的课程&#xff0c;有了理论支持再运用在工作中&#xff0c;积累经验。 建议去考一个NPDP证书&#xff0c;这个证书是很多大厂的求职门槛了&#xff0c;要求“有npdp产品经理的”优先 一、什么是NPDP&#xff1f; NPDP 是产品经理国际资格认证&a…

MySQL线上死锁案例分析

项目场景 项目开发中有两张表&#xff1a;c_bill(账单表)&#xff0c;c_bill_detail(账单明细表)&#xff0c;他们的表结构如下&#xff08;这里只保留必要信息&#xff09;&#xff1a; CREATE TABLE c_bill_detail (id bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 主…

中华鲲鹏 深耕湾区 华鲲振宇重磅亮相第二届数字政府建设峰会

12月8日,由国家互联网信息办公室指导,广东省人民政府、香港特别行政区政府、澳门特别行政区政府联合主办的第二届数字政府建设峰会暨“数字湾区”发展论坛在广州开幕。第十二届全国政协副主席、国家电子政务专家委员会主任王钦敏,中央宣传部副部长、中央网信办主任、国家网信办…

Profibus、Profinet、Ethernet有什么区别?

PROFINET 是一种新的以太网通讯系统&#xff0c;是由西门子公司和 Profibus 用户协会开发。 PROFINET 具有多制造商产品之间的通讯能力&#xff0c;自动化和工程模式&#xff0c;并针对分布式智能自动化系统进行了优化。其应用结果能够大大节省配置和调试费用。 PROFINET 系统集…

@svelte-dev/auth 一个简单好用的 Svelte 身份管理库

特性 完全的服务器端身份验证完整的TypeScript支持策略-基础身份验证轻松处理成功和失败实现自定义策略支持持久会话概述 Svelte Auth是一个完整的开源身份验证解决方案,适用于Svelte应用程序。 深受Passport.js和Remix-Auth的启发,但完全从头开始重写,以便在Web Fetch AP…

el-date-picker 限制选择范围最大为一年,设置快捷选项,设置默认时间

el-date-picker 限制选择范围最大为一年&#xff1a; 主要代码为&#xff1a;:picker-options"pickerOptions" 以及 blur"pickerBlur" <el-date-pickerv-model"transactionTime"type"daterange"style"width: 200px"size…

数字工厂管理系统建设层级分为哪几层

随着工业4.0时代的到来&#xff0c;数字工厂已成为制造业转型升级的必经之路。数字工厂管理系统作为数字工厂的核心组成部分&#xff0c;对于提高生产效率、降低成本、提升质量等方面具有重要意义。数字工厂管理系统的建设层级一般分为以下几个层次&#xff0c;本文将对其进行详…

LLM Agent发展演进历史(观看metagpt视频笔记)

LLM相关的6篇重要的论文&#xff0c;其中4篇来自谷歌&#xff0c;2篇来自openai。技术路径演进大致是&#xff1a;SSL (Self-Supervised Learning) -> SFT (Supervised FineTune) IT (Instruction Tuning) -> RLHF。 word embedding的问题&#xff1a;新词如何处理&…

【计算思维】第14届蓝桥杯省赛计算思维U10组真题

选择题 第 1 题 单选题 晶晶在注册一个学习网站时&#xff0c;需要设置密码。 网站提示&#xff1a; 密码必须由 8~16 个字符组成&#xff0c;可以包含数字、大写字母、小写字母、特殊符号这 4 种 字符类型。 包含 4 种不同类型字符的密码是强密码&#xff1b; 包含 2 种或 …

全国合作商标服大赛决赛完整规则流程

本文是全国合作商标服大赛决赛完整规则流程&#xff0c;有需要的朋友可以参考下。 一、抢答比拼 1、政策管理考核题 系统评分。抢答题共15题/条线&#xff1a;单选10题&#xff0c;多选5题&#xff0c;基础分100分 单选答对10分/答错-5分&#xff0c;多选答对20分/答错-10分…

编译原理lab3-cminus_compiler-LLVM简要熟悉

lab3实验报告&#xff0c;我的实验报告图例很少&#xff0c;这次只有两张图&#xff0c;其余的都以复制输出的形式展现出来了&#xff0c;最终提交的代码在最后 [[#你的提交|你的提交]][[#实验设计|实验设计]][[#提交一&#xff1a;手动编写.ll|提交一&#xff1a;手动编写.ll…

Redis - 做缓存时高并发问题:缓存穿透、击穿、雪崩,数据库缓存双写不一致

缓存穿透 当用户访问的数据既不在缓存也不在数据库中时&#xff0c;就会导致每个用户查询都会“穿透” 缓存“直抵”数据库。这种情况就称为缓存穿透。当高度发的访问请求到达时&#xff0c;缓存穿透不 仅增加了响应时间&#xff0c;而且还会引发对 DBMS 的高并发查询&…

frp配置内网穿透步骤

frp配置内网穿透步骤 1.环境准备1.1 云服务器1.2 frp包 2. frp安装2.1 server服务端设置2.2 客户端配置 实现目标通过云服务器ip:8080访问内网电脑启动的web项目localhost:8080 1.环境准备 1.1 云服务器 服务器安装centos7.9, 安全组入口方向开通 7500 7000 8080 8060端口 …

CSDN云账号签约流程

在电脑端上进行提现操作&#xff0c;按提示进行即可。 问题 手机端无法签约。 电脑签约

【详解优先级队列(堆)】

目录 堆的概念 堆的性质 堆的存储方式 堆的创建 堆的向下调整 向下过程(以小堆为例) 向下过程(以大堆为例) 建堆的时间复杂度O(n) 堆的插入与删除 堆的插入 向上调整建堆的时间复杂度O(nlogn) 堆的删除 常见习题 常用接口介绍 PriorityQueue的特性 Pri…

HNU计算机视觉作业一

前言 选修的是蔡mj老师的计算机视觉&#xff0c;上课还是不错的&#xff0c;但是OpenCV可能需要自己学才能完整把作业写出来。由于没有认真学&#xff0c;这门课最后混了80多分&#xff0c;所以下面作业解题过程均为自己写的&#xff0c;并不是标准答案&#xff0c;仅供参考 …

lammps编译(2Aug2023、intel2020、rtx4070ti)

说明&#xff1a; [rootnode101 ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) [rootnode101 ~]# gcc -v Using built-in specs. COLLECT_GCCgcc COLLECT_LTO_WRAPPER/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper Target: x86_64-redhat-lin…