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

这是最好的时代,这是最坏的时代,我们一无所有,我们巍然矗立
本文由@睡觉待开机原创,未经允许不得转载。
本内容在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语言常用的针对字符串操作的函数,有利于加深对字符串的理解。
感谢您阅读本文。如果您有任何问题或需要进一步了解,请随时联系我。祝您一切顺利!

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

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

相关文章

TPCTF maze——WP

解包&#xff0c;收集文件信息 先解包 反编译chal.pyc 核心逻辑在maze.so&#xff0c;chal.pyc导入了maze里面的run函数执行&#xff0c;maze是用Cython编译的 用strings查看可以看出是cython3.0.5版本编译的 获取符号表信息的两种方式 使用help读取 我们可以使用这个函数来…

【数据结构】什么是堆?

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 堆的概念及结构 堆的定义如下: n个元素的序列{k1,k2,...,kn}当且仅当满足以下关系时,称之为堆. 或 把这个序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个…

理解 Proxy 和 Object.defineProperty:提升你的 JavaScript 技能(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

【01分数规划】ABC324F

[ABC324F] Beautiful Path - 洛谷 思路 首先看到这个形式很容易想到 01 分数规划&#xff0c;即去二分答案&#xff0c;然后就是转化成 是否存在一个路径使得 sigma b - mid * sigma c > 0 显然只需要改变一下边权&#xff0c;跑一遍最长路即可 #include <bits/stdc.h…

html 中vue3 的setup里调用element plus的弹窗 提示

引入Elementplus之后&#xff0c;在setup&#xff08;&#xff09;方法外面导入ElMessageBox const {ElMessageBox} ElementPlus 源码 &#xff1a; <!DOCTYPE html> <html> <head><meta charset"UTF-8"><!-- import Vue before Elemen…

运筹优化 | 模拟退火求解旅行商问题 | Python实现

"""模拟退火旅行商""" import random import numpy as np import math import time import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False location np.loadtxt(city_location.t…

python-爬取壁纸

代理池的&#xff0c;防止IP 被封 找到图片真实地址 现在看到的只是图片的预览地址 (previews) 1.检查&#xff1a; 2.鼠标变为箭头时查看网页源代码 关于怎样在源代码中找到图片的真实地址 ??? 为什么在源代码界面 ctrl f 时候搜索的是 .png ??? 首先图片地址是以 .j…

OpenStack网络详解

本文主要解释了OpenStack在安装完毕——创建网段与dhcp——创建虚拟机的过程中&#xff0c;系统中多出来的这一堆网卡到底分别连接哪两部分的网卡&#xff0c;以及哪些设备是虚拟出来的。 拓扑 红色代表ovs与网桥 蓝色代表命名空间或者虚机 绿色代表网卡 网络概况 openstack安…

【Mars3d-ModelEntity】实现gltf模型不随地图缩放而改变大小

需求场景&#xff1a; 1.实现gltf模型不随地图缩放而改变大小 相关代码&#xff1a; const graphic new mars3d.graphic.ModelEntity({ name: "警车", position: [116.346929, 30.861947, 401.34], style: { url: "//data.mars3d.cn/gltf/mars/jingche/jingc…

SpringBoot进行自然语言处理,利用Hanlp进行文本情感分析

. # &#x1f4d1;前言 本文主要是SpringBoot进行自然语言处理&#xff0c;利用Hanlp进行文本情感分析&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风…

[Unity+文心知识库]使用百度智能云搭建私有知识库,集成知识库API,打造具备知识库的AI二次元姐姐

1.简述 最近从百度智能云的官方技术支持那边了解到&#xff0c;目前百度千帆大模型平台提供有在线的知识库功能&#xff0c;能够在线上传自己的私人知识库文档&#xff0c;并且配置文心一言模型作为文本生成的引擎&#xff0c;构建自己的私有知识库。之前自己搭建知识库都是用的…

bugku--源代码

查看源代码 发显URL编码 解码 在拼接这一串 拿着去提交就行啦

【Vue】vue增加导航标签

系列文章 【C#】WebAPI&#xff0c;在Windows IIS平台部署 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/126539836 【Vue】vue&#xff0c;在Windows IIS平台部署 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/13385…

docker compose部署wordpress

准备机器&#xff1a; 192.168.58.151 &#xff08;关闭防火墙和selinux&#xff09; 安装好docker服务 &#xff08;详细参照&#xff1a;http://t.csdnimg.cn/usG0s 中的国内源安装docker&#xff09; 部署wordpress: 创建目录&#xff1a; [rootdocker ~]# mkdir…

Selenium库自动化测试入门

前言 为什么要学selenium&#xff1f;&#xff1f;前面已经学了requests库我们会发现 对于绝大多数动态渲染的网页来说&#xff0c;用requests进行爬虫比较繁琐。 所以我们还是要学习一下selenium库&#xff0c;以帮助我们更高效的爬取网页。 环境&#xff1a; pychar 202…

flutter调试器查看不了副页面(非主页面/子页面)

刚接触flutter&#xff0c;写了两个页面&#xff0c;通过按钮&#xff0c;可以从主页面跳转到副页面&#xff0c;副页面我自己写的一个独立的dart文件&#xff0c;在主页面的代码中导入使用。但是当我运行代码后&#xff0c;点击跳转的时候&#xff0c;却发现查看不到对应的副页…

Linux驱动入门 —— 利用引脚号操作GPIO进行LED点灯

目录 一、字符设备驱动程序框架 编写驱动程序的步骤&#xff1a; 对于 LED 驱动&#xff0c;我们想要什么样的接口&#xff1f; LED 驱动能支持多个板子的基础&#xff1a;分层思想 二、Linux驱动如何指向一个GPIO 直接通过寄存器来操作GPIO 利用引脚号操作GPIO IMX6UL…

STM32的看门狗(WDG)

WDG&#xff08;Watchdog&#xff09;看门狗 看门狗可以监控程序的运行状态&#xff0c;当程序因为设计漏洞、硬件故障、电磁干扰等原因&#xff0c;出现卡死或跑飞现象时&#xff0c;看门狗能及时复位程序&#xff0c;避免程序陷入长时间的罢工状态&#xff0c;保证系统的可靠…

基于C/C++的rapidxml加载xml大文件 - 下部分

下载地址: RapidXml (sourceforge.net)https://rapidxml.sourceforge.net/ 将源码添加到自己的工程中 示例测试大文件耗时: 总共293w行数据&#xff0c;大概耗时不到1s。

Paper Reading: (U2PL) 基于不可靠伪标签的半监督语义分割

目录 简介目标/动机方法Pseudo-LabelingUsing Unreliable Pseudo-Labels 补充知识InfoNCE LossOHEM 实验Comparison with Existing AlternativesAblationEffectiveness of Using Unreliable Pseudo-LabelsAlternative of Contrastive Learning 总结附录U2PL 与 negative learni…