字符串函数能有什么坏心思?

news2024/12/25 16:10:12

在这里插入图片描述

🚀write in front🚀
📝个人主页:认真写博客的夏目浅石.
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏:夏目的C语言宝藏
💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🖊
✉️如果无聊的话,就来逛逛我的博客栈吧stack-frame.cn

文章目录

  • 前言
  • 函数介绍以及模拟实现
    • 1.1 strlen函数
    • 1.2 strcpy函数
    • 1.3 strcat函数
    • 1.4 strcmp函数
    • 1.5 strncpy函数
    • 1.6 strncat函数
    • 1.7 strncmp函数
    • 1.8 strstr函数
    • 1.9 strtok函数
    • 1.10 strerror函数
    • 1.11 memcpy函数
    • 1.12 memmove函数
    • 1.13 memcmp函数
  • 总结


前言

函数的学习离不开这些


提示:以下是本篇文章正文内容,下面案例可供参考

函数介绍以及模拟实现

1.1 strlen函数

size_t strlen ( const char * str );
  • 字符串已经'\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。
  • 参数指向的字符串必须要以 '\0' 结束。
  • 注意函数的返回值为size_t,是无符号的

设置为size_t的原因介绍:

strlen求字符串长度的,求出的长度是不可能为负数的
所以返回类型设置为size_t也是合情合理的
typedef unsigned int size_t

验证代码:

#include<stdio.h>
#include<string.h>

int main()
{
	//数学上:3-6=-3;
	//实际上:size_t所以俩差值是一个很大的数 
	if(strlen("abc") - strlen("abcdef") > 0)
	{
		printf(">\n");
	}
	else
	{
		printf("<=\n");
	}
	
	return 0;
}

运行图示:
在这里插入图片描述

strlen函数的模拟实现

方法一:遍历法

#include<stdio.h>
#include<assert.h>
int my_strlen(char* str)
{
	assert(str != NULL);
	int cnt=0;
	while(*str!='\0')
	{
		cnt++;
		str++;
	}
	return cnt;
}
int main()
{
	char arr[]="abcdef";
	int len=my_strlen(arr);
	printf("%d\n",len);
	return 0;
}

方法二:递归法

#include<stdio.h>
#include<assert.h>
int my_strlen(const char* str)
{
	assert(str!=NULL);
	if(*str!='\0')
		return 1+my_strlen(str+1);
	else return 0;
}
int main()
{
	char arr[]="abcdef";
	int len=my_strlen(arr);
	printf("%d\n",len);
	return 0;
}

方法三:减指法

#include<stdio.h>
#include<assert.h>
int my_strlen(const char* str)
{
	assert(str!=NULL);
	if(*str!='\0')
		return 1+my_strlen(str+1);
	else return 0;
}
int main()
{
	char arr[]="abcdef";
	int len=my_strlen(arr);
	printf("%d\n",len);
	return 0;
}

1.2 strcpy函数

char* strcpy(char * destination, const char * source );
  • Copies the C string pointed by source into the array pointed by destination, including theterminating null character (and stopping at that point).
  • 源字符串必须以 '\0' 结束。
  • 会将源字符串中的 '\0' 拷贝到目标空间。
  • 目标空间必须足够大,以确保能存放源字符串。
  • 目标空间必须可变。

strcpy函数的模拟实现

方法一:遍历法

#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest , const char* src)
{
	char *ret=dest;
	assert(dest&&src);
	while(*dest++ = *src++)
	{
		;
	}
	return ret;
}

int main()
{
	char arr[]="xxxxxxxxxx";
	char a[]="abcdef";
	my_strcpy(arr,a);
	
	printf("%s",arr);
	return 0;
}

方法二:遍历法

#include<stdio.h>
#include<assert.h>
void my_strcpy(const char*str,char* ptr)
{
	assert(str!=NULL);
	assert(ptr!=NULL);
	while(*str!='\0')
	{
		*ptr=*str;
		str++;
		ptr++;
	}
}
int main()
{
	char arr[]="xxxxxxxxxx";
	char a[]="abcdef";
	my_strcpy(arr,a);
	
	printf("%s",arr);
	return 0;
}

1.3 strcat函数

char * strcat ( char * destination, const char * source );
  • Appends a copy of the source string to the destination string. The terminating null characterin destination is overwritten by the first character of source, and a null-character is includedat the end of the new string formed by the concatenation of both in destination.
  • 源字符串必须以 '\0' 结束。
  • 目标空间必须有足够的大,能容纳下源字符串的内容。
  • 目标空间必须可修改。

函数的使用:

#include<stdio.h>
#include<assert.h>
#include<string.h>

int main()
{
	char arr[20]="hello ";
	strcat(arr,"world");
	printf("%s",arr); 
	
	return 0;
}

在这里插入图片描述

strcat函数的模拟实现

#include<stdio.h>
#include<assert.h>
#include<string.h>

char* my_strcat(char* dest,const char* src)
{
	assert(dest && src);
	char* start= dest;
	//1.寻找'\0'
	while(*dest)
	{
		dest++;
	}
	//2.追加
	while(*dest++ = *src++)
	{
		;
	}
	return start; 
}

int main()
{
	char arr[20]="hello ";
	my_strcat(arr,"world");
	printf("%s",arr); 
	return 0;
}

1.4 strcmp函数

int strcmp ( const char * str1, const char * str2 );
  • This function starts comparing the first character of each string. If they are equal to eachother, it continues with the following pairs until the characters differ or until a terminatingnull-character is reached.
  • 第一个字符串大于第二个字符串,则返回大于0的数字
  • 第一个字符串等于第二个字符串,则返回0
  • 第一个字符串小于第二个字符串,则返回小于0的数字

strcmp函数的模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>

int my_strcmp(const char* str1,const char* str2)
{
	assert(str1 && str2);
	while(*str1 == *str2)
	{
		if(*str1=='\0')
			return 0;
		str1++;
		str2++;
	}
//	if(*str1 > *str2)
//		return 1;
//	else
//		return -1;
	return *str1 - *str2;
}

int main()
{
	char arr1[]="ab";
	char arr2[]="abcde";
	int ret=my_strcmp(arr1,arr2);
	printf("%d\n",ret);
	
	return 0;
}

1.5 strncpy函数

char * strncpy ( char * destination, const char * source, size_t num );
  • Copies the first num characters of source to destination. If the end of the source C string(which is signaled by a null-character) is found before num characters have been copied,destination is padded with zeros until a total of num characters have been written to it.
  • 拷贝num字符从源字符串到目标空间。
  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

函数的使用:

#include<stdio.h>
#include<string.h>
#include<assert.h>

int main()
{
	char arr1[20]="xxxxxxxxxx";
	strncpy(arr1,"abcdef",3);
	printf("%s\n",arr1);
	
	return 0;
}

在这里插入图片描述

1.6 strncat函数

char * strncat ( char * destination, const char * source, size_t num );
  • Appends the first num characters of source to destination, plus a terminating null-character.
  • If the length of the C string in source is less than num, only the content up to the terminatingnull-character is copied

函数的使用:

#include <stdio.h>
#include <string.h>
int main ()
{
 	char str1[20];
 	char str2[20];
 	strcpy (str1,"To be ");
 	strcpy (str2,"or not to be");
 	strncat (str1, str2, 6);
 	puts (str1);
 	return 0;
}

1.7 strncmp函数

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

函数的使用:

#include <stdio.h>
#include <string.h>
int main ()
{
  	char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
  	int n;
  	puts ("Looking for R2 astromech droids...");
  	for (n=0 ; n<3 ; n++)
  	if (strncmp (str[n],"R2xx",2) == 0)
 	{
   	 	printf ("found %s\n",str[n]);
 	}
  return 0;
}

1.8 strstr函数

char * strstr ( const char *str1, const char * str2);
  • Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.

函数的使用:

#include<stdio.h>
#include<string.h>
#include<assert.h>

int main()
{
	char arr1[]="abbbbcdef";
	char arr2[]="bbcd";
	char* ret=strstr(arr1,arr2);
	if(ret==NULL)
	{
		printf("找不到\n");
	}	
	else
	{
		printf("%s\n",ret); 
	}
	
	return 0;
}

模拟实现:

#include<stdio.h>
#include<string.h>
#include<assert.h>

char* my_strstr(char* str1,char* str2)
{
	assert(str1&&str2);
	if(*str2=='\0')
	{
		return str1;
	}
	char* s1=str1;
	char* s2=str2;
	char* cp=str1;
	while(*cp)
	{
		s1=cp;
		s2=str2;
		while(*s1!='\0' && *s2!='\0' && *s1==*s2)
		{
			++s1;
			++s2;
		}
		if(*s2=='\0')
		{
			return cp;
		}
		cp++;
	}
	return NULL;
}

int main()
{
	char arr1[]="abbbbcdef";
	char arr2[]="bbcd";
	char* ret= my_strstr(arr1,arr2);
	if(ret==NULL)
	{
		printf("找不到\n");
	}	
	else
	{
		printf("%s\n",ret); 
	}
	
	return 0;
}

1.9 strtok函数

char * strtok ( char * str, const char * sep );
  • sep参数是个字符串,定义了用作分隔符的字符集合
  • 第一个参数指定一个字符串,它包含了0个或者多个sep字符串中一个或者多个分隔符分割的标记。
  • strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:
    strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容
    并且可修改。)
  • strtok函数的第一个参数不为 NULL ,函数将找到str第一个标记strtok函数将保存它在字符串中的位置。
  • strtok函数的第一个参数NULL函数将在同一个字符串中被保存的位置开始,查找下一个标
    记。
  • 如果字符串中不存在更多的标记,则返回 NULL 指针。
#include<stdio.h>
#include<string.h>

int main()
{
	char arr[]="192#168.120.85";
	char* p="#.";
	char buf[20]={0};
	strcpy(buf,arr);
	char* ret=NULL;
	for(ret=strtok(buf,p);ret!=NULL;ret=strtok(NULL,p))
	{
		printf("%s\n",ret);
	}
	
	return 0;
}

1.10 strerror函数

char * strerror ( int errnum );
  • 返回错误码,所对应的错误信息。

在这里插入图片描述

1.11 memcpy函数

void * memcpy ( void * destination, const void * source, size_t num );
  • 函数memcpysource的位置开始向后复制num个字节的数据到destination的内存位置。
  • 这个函数在遇到 '\0' 的时候并不会停下来
  • 如果sourcedestination有任何的重叠,复制的结果都是未定义的

模拟实现:

#include<stdio.h>
#include<string.h>
#include<assert.h>

void* my_memcpy(void* dest,const void* src,size_t num)
{
	void* ret=dest;
	assert(dest&&src);
	while(num--)
	{
		*(char*)dest=*(char*)src;
		dest=(char*)dest+1;
		src=(char*)src+1;
	}
	return ret;
}

int main()
{
	int arr1[]={1,2,3,4,5,6,7,8,9,10};
	int arr2[10]={0};
	
	my_memcpy(arr2,arr1+2,20);
	
	return 0;
}

1.12 memmove函数

void * memmove ( void * destination, const void * source, size_t num );
  • memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
  • 如果源空间和目标空间出现重叠,就得使用memmove函数处理。

模拟实现:

#include<stdio.h>
#include<assert.h>

void* my_memmove(void* dest,const void* src,size_t num)
{
	void* ret=dest;
	assert(dest&&src);
	
	if(dest<src)
	{
		while(num--)
		{
			*(char*)dest=*(char*)src;
			dest=(char*)dest+1;
			src=(char*)src+1;
		}
	}
	else
	{
		while(num--)
		{
			*((char*)dest+num)=*((char*)src+num);
		}
	}
	return ret;
}

int main()
{
	int arr[]={1,2,3,4,5,6,7,8,9,10};
	my_memmove(arr,arr+2,20);
	for(int i=0;i<10;i++)
	{
		printf("%d ",arr[i]);
	}
	puts("");
	return 0;
}

1.13 memcmp函数

int memcmp ( const void * ptr1, const void * ptr2, size_t num );
  • 比较从ptr1和ptr2指针开始的num个字节
  • 返回值如下:
    在这里插入图片描述
#include<stdio.h>
#include<string.h>

int main()
{
	int arr1[]={1,2,6};
	int arr2[]={1,2,5};
	int ret=memcmp(arr1,arr2,9);
	printf("%d\n",ret);
	
	return 0;
}

在这里插入图片描述

总结

本期学习了很多字符串相关的函数,包括基本用法和模拟实现,都给大家书写了出来,希望大家可以多敲一遍加深对于函数的印象

我是夏目浅石,希望和你一起学习进步,刷题无数!!!希望各位大佬能一键三连支持一下博主,hhhh~我们下期见喽

在这里插入图片描述
如果无聊的话,就来逛逛我的博客栈吧stack-frame.cn

原创不易,还希望各位大佬支持一下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下

👍 点赞,你的认可是我创作的动力! \textcolor{9c81c1}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!

⭐️ 收藏,你的青睐是我努力的方向! \textcolor{ed7976}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富! \textcolor{98c091}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!

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

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

相关文章

又发现一个ChatGPT国内镜像站,无次数限制也无广告

ChatGPT 美国OpenAI研发的聊天机器人程序&#xff0c;于2022年11月30日发布。ChatGPT是人工智能技术驱动的自然语言处理工具&#xff0c;它能够通过学习和理解人类的语言来进行对话&#xff0c;还能根据聊天的上下文进行互动&#xff0c;真正像人类一样来聊天交流&#xff0c;…

传统目标检测实战:Sift/ORB+Match

传统目标检测实战&#xff1a;Sift/ORBMatch 文章目录传统目标检测实战&#xff1a;Sift/ORBMatch1. 前言2. 先验知识3. 项目框架4. 工具函数&#xff08;utils.py&#xff09;5. 检测待测图像&#xff08;test_xxxx.py&#xff09;5.1 使用图像缩放金字塔&#xff08;test_PG.…

大数据技术架构(组件)31——Spark:Optimize--->JVM On Compute

2.1.9.4、Optimize--->JVM On Compute首要的一个问题就是GC,那么先来了解下其原理&#xff1a;1、内存管理其实就是对象的管理&#xff0c;包括对象的分配和释放&#xff0c;如果显式的释放对象&#xff0c;只要把该对象赋值为null&#xff0c;即该对象变为不可达.GC将负责回…

ISYSTEM调试实践9-winIDEA Analyzer功能2

上一篇文章介绍了如何启动Trace,并配置。本文简单介绍一下Analyzer的输出结果&#xff0c;具体每个窗口的内容。 1、程序溯源 Profiler Timeline介绍了函数在时间轴上的执行调用情况。鼠标左键可以设置具体时间点&#xff0c;CTRL 左键和CTRL 右键设置观测的时间窗口&#xf…

技术树基础——16排它平方数(Bigdecimal,int,string,数组的转换)

题目&#xff1a;03879 * 203879 41566646641这有什么神奇呢&#xff1f;仔细观察&#xff0c;203879 是个6位数&#xff0c;并且它的每个数位上的数字都是不同的&#xff0c;并且它平方后的所有数位上都不出现组成它自身的数字。具有这样特点的6位数还有一个&#xff0c;请你…

openFeign源码学习

openFeign这个框架要解决的问题是&#xff1a;通常在调用远程接口的时候&#xff0c;如果是http请求&#xff0c;需要我们通过restTemplate去拼接调用参数和连接&#xff0c;然后发起调用&#xff0c;openFeign帮我们把拼接参数的这个过程包装了起来&#xff0c;通过代理对象的…

[WUSTCTF2020]level1 题解

1.查壳 64bit elf 还有一个文本文件&#xff0c;打开 打开是一串数字 根据这个txt文件的名称Output&#xff0c;可以猜测&#xff0c;这个文件的内容可能是程序的输出 2.静态分析 找到main函数反汇编 v7 __readfsqword(0x28u); stream fopen("flag", "r…

二叉搜索树之AVL树

AVL树的概念二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。因此&#xff0c;两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年 发明了一种解决上…

PCCW-HKT Futurera NFT 作品集来袭!

欢迎来到 Futurera&#xff0c;未来的虚拟城市&#xff01; 凭借庞大的 web2 资源&#xff0c;在全球首创的虚拟 5G 移动网络技术的鼎力支持下&#xff0c;Futurera 正力争跨越元宇宙的边界。 NFT 系列介绍 为庆祝 The Sandbox 中 Futurera 体验的开放&#xff0c;我们发布了一…

LSTM已死,Transformer当立(LSTM is dead. Long Live Transformers! ):下

2017 年,Google 在论文 Attention is All you need 中提出了 Transformer 模型,其使用 Self-Attention 结构取代了在 NLP 任务中常用的 RNN 网络结构。而且实验也证明Transformer 在效果上已经完败传统的 RNN 网络。Transformer 的整体模型架构如下图所示。尽管它看起来还是很…

python网络爬虫—快速入门(理论+实战)(七)

系列文章目录 &#xff08;1&#xff09;python网络爬虫—快速入门&#xff08;理论实战&#xff09;&#xff08;一&#xff09; &#xff08;2&#xff09;python网络爬虫—快速入门&#xff08;理论实战&#xff09;&#xff08;二&#xff09; &#xff08;3&#xff09; p…

平价款的血糖血压监测工具,用它养成健康生活习惯,dido F50S Pro上手

之前看有数据显示国内的三高人群越来越年轻&#xff0c;很多人不到三十就有了高血压、高血糖的问题&#xff0c;埋下了不小的健康隐患&#xff0c;加上前阵子的疫情管控放松&#xff0c;人们了解到了新冠病毒对心脏负担的认知&#xff0c;预防慢病被大众提上了日程&#xff0c;…

获取成员userID

文章目录一、简介二、获取token1、获取秘钥2、获取Token三、获取部门数据1、获取部门列表2、获取子部门ID列表3、获取单个部门详情四、获取成员信息1、读取成员2、获取部门成员3、获取部门成员详情一、简介 同步数据到企微&#xff1a; 企业如果需要从自有的系统同步通讯录到…

操作系统systemd启动自启服务进程

概念与背景 Systemd 是 Linux 系统工具&#xff0c;用来启动守护进程&#xff0c;已成为大多数发行版的标准配置。历史上&#xff0c;Linux 的启动一直采用init进程。在ubuntu18.04以后&#xff0c;都采用systemd启动。 更换主要原因是init进程有两个原因 启动时间长。init进…

Java高级-多线程

本篇讲解java多线程 基本概念&#xff1a; 程序、进程、线程 **程序(program)**是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码&#xff0c;静态对象。 **进程(process)**是程序的一次执行过程&#xff0c;或是正在运行的一个程序。是一个动态的过程…

12年老外贸的经验分享

回想这12年的经历&#xff0c;很庆幸自己的三观一直是正确的&#xff0c;就是买家第一不管什么原因&#xff0c;只要你想退货&#xff0c;我都可以接受退款。不能退给上级供应商&#xff0c;我就自己留着&#xff0c;就是为了避免因为这个拒收而失去买家。不管是什么质量原因&a…

2022年11月软考领证通知

纸质证书领取时间 根据往年各地软考证书的领取时间看&#xff0c;上半年软考证书领取一般在10月底陆续开始&#xff0c;下半年的证书领取时间一般在次年2/3月份左右开始&#xff08;各地证书领取具体时间不一样&#xff0c;届时请多留意当地证书领取通知。&#xff09; 1、证…

PyTorch学习笔记:nn.LeakyReLU——LeakyReLU激活函数

PyTorch学习笔记&#xff1a;nn.LeakyReLU——LeakyReLU激活函数 功能&#xff1a;逐元素对数据应用如下函数公式进行激活 LeakyReLU(x)max⁡(0,x)α∗min⁡(0,x)\text{LeakyReLU}(x)\max(0,x)\alpha*\min(0,x) LeakyReLU(x)max(0,x)α∗min(0,x) 或者 LeakyReLU(x){x,ifx≥0α…

在浏览器输入url到发起http请求,这过程发生了什么

当用户输入url&#xff0c;操作系统会将输入事件传递到浏览器中&#xff0c;在这过程中&#xff0c;浏览器可能会做一些预处理&#xff0c;比如 Chrome 会根据历史统计来预估所输入字符对应的网站&#xff0c;例如输入goog&#xff0c;根据之前的历史发现 90% 的概率会访问「ww…

1理想的大数据处理框架设计

以下内容基于极客 蔡元楠老师的《大规模数据处理实战》做的笔记哈。感兴趣的去极客看蔡老师的课程即可。 MapReduce 缺点 高昂的维护成本 因为mapreduce模型只有map和reduce两个步骤。所以在处理复杂的架构的时候&#xff0c;需要协调多个map任务和多个reduce任务。 例如计…