C语言——字符函数和字符串函数【详解】(一)

文章目录

  • 函数介绍
  • 1.strlen
  • 2.strcpy
  • 3. strcat
  • 4. strcmp
  • 5. strncpy
  • 6. strncat
  • 7. strncmp
  • 8. strstr

函数介绍

  • 求字符串长度

strlen

  • 长度不受限制的字符串函数(使用时不安全)

strcpy
strcat
strcmp

  • 长度受限制的字符串函数介绍(与长度不受限制函数比较时使用相对安全)

strncpy
strncat
strncmp

  • 字符串查找

strstr
strtok

  • 错误信息报告

strerror

  • 字符操作
  • 内存操作函数

memcpy
memmove
memset
memcmp

1.strlen

计算字符串长度的函数

size_t strlen ( const char * str );

注:

  • 字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
  • 参数指向的字符串必须要以 ‘\0’ 结束。
  • 注意函数的返回值为size_t,是无符号的( 易错 )
  • 学会strlen函数的模拟实现

代码演示:

#include <stdio.h>
#include <string.h>
//strlen函数的返回类型是size_t - 无符号整型
int main()
{
	if (strlen("abc") - strlen("abcdef") > 0)
	{
		printf(">\n");
	}
	else
	{
		printf("<=\n");
	}
	return 0;
}

因为size_t 是无符号整型,所以-3会被理解成无符号数3,所以大于0输出>

打印结果:
在这里插入图片描述

strlen函数的模拟实现

  1. 计数器
  2. 函数
  3. 指针 - 指针

1. 计数器

#include <stdio.h>
#include <assert.h>
int my_strlen(const char* str)
{
	int count = 0;
	assert(str);//断言,判断指针是否为空指针
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}
int main()
{
	char arr[] = "bit";
	int len = my_strlen(arr);
	printf("%d\n", len);

	return 0;
}

打印结果:
在这里插入图片描述
2. 递归

//不创建临时变量,求字符串长度
int my_strlen(const char* str)
{
	if (*str != '\0')
		return 1 + my_strlen(str + 1);
	else
		return 0;
}
int main()
{
	char arr[] = "bit";
	int len = my_strlen(arr);
	printf("%d\n", len);

	return 0;
}

运行结果:
在这里插入图片描述
3.指针 - 指针

#include <stdio.h>
#include <assert.h>
int my_strlen(const char* str)
{
	assert(str != NULL);
	char* start = str;//strt里装的是首元素b的地址
	while (*str != '\0')
	{
		str++;
	}
	return str - start;//指针-指针为两个指针之间的元素个数
}
int main()
{
	char arr[] = "bit";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

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

2.strcpy

拷贝函数:将一个字符串的内容拷贝到另一个字符串(包括\0)

在这里插入图片描述
看代码:

#include <stdio.h>
int main()
{
	char arr1[] = "abcdef";
	char arr2[20] = { 0 };
	strcpy(arr2, arr1);
	printf("%s\n", arr2);
}

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

注:

  • 源字符串必须以 ‘\0’ 结束。
  • 会将源字符串中的 ‘\0’ 拷贝到目标空间。
  • 目标空间必须足够大,以确保能存放源字符串。
  • 目标空间必须可变。
  • 学会模拟实现

模拟实现

#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 arr1[] = "hehe";
	char arr2[20] = { 0 };
	my_strcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

3. strcat

追加函数:其实就是把又一个字符串加在了前一个字符串的后面

在这里插入图片描述
代码演示:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "hello ";
	char arr2[] = "world";
	//追加
	strcat(arr1, arr2);
	printf("%s\n", arr1);

	return 0;
}

注:

  • 源字符串必须以 ‘\0’ 结束。
  • 目标空间必须有足够的大,能容纳下源字符串的内容。
  • 目标空间必须可修改。且必须有\0

模拟实现

#include <stdio.h>
#include <assert.h>
#include <string.h>
char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);
	char* ret = dest;
	//找目标空间中的\0
	while (*dest != '\0')
	{
		dest++;
	}
	//拷贝
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[20] = "hello ";
	char arr2[] = "world";
	//追加
	my_strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

画图理解:
在这里插入图片描述
打印结果:
在这里插入图片描述

字符串自己给自己追加,如何?
答:会循环拷贝下去,没有停下来的时候了
在这里插入图片描述
因为\0会被覆盖,所以找不到\0循环不会停止

4. strcmp

字符串比较函数:比较2个字符串的内容的时候,不能使用==,应该使用strcmp

在这里插入图片描述
代码演示:

#include <stdio.h>
int main()
{
	char arr1[] = "abqcc";
	char arr2[] = "abq";
	int ret = strcmp(arr1, arr2);
	printf("%d\n", ret);
	return 0;
}

运行结果:
在这里插入图片描述
注:

strcmp函数比较的是对应位置上的ASCII值的比较
标准规定:

  • 第一个字符串大于第二个字符串,则返回大于0的数字
  • 第一个字符串等于第二个字符串,则返回0
  • 第一个字符串小于第二个字符串,则返回小于0的数字

模拟实现

#include <stdio.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++;
	}
	return *str1 - *str2;
}
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcd";
	int ret = my_strcmp(arr1, arr2);
	printf("%d\n", ret);
	return 0;
}

打印结果:
在这里插入图片描述
切记:当第一个字符串大于第二个字符串时,返回的是大于0的数,并不是具体的某个数

5. strncpy

长度受限制的拷贝函数,suze_t num表示拷贝几个数

在这里插入图片描述
代码演示:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[] = "abcdef";
	char arr2[5] = {0};
	strncpy(arr2, arr1, 3);
	printf("%s\n", arr2);
	return 0;
}

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

  • 拷贝num个字符从源字符串到目标空间。
  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

6. strncat

长度受限制的追加函数

在这里插入图片描述
代码演示:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[20] = "hello ";
	char arr2[] = "abcdef";
	strncat(arr1, arr2, 3);
	printf("%s\n", arr1);
	return 0;
}

运行结果;
在这里插入图片描述

strncat函数追加完后会在后边补一个\0
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加\0,不会追加到num的长度
strncat函数是可以自己给自己追加的

7. strncmp

长度受限制的比较函数

在这里插入图片描述

代码演示:

#include <stdio.h>
#include <string.h>
 int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcq";
	int ret = strncmp(arr1, arr2, 4);
	printf("%d\n", ret);
	return 0;
}

运行结果:

在这里插入图片描述

  • 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。在这里插入图片描述

8. strstr

在str1中找str2第一次出现的位置,如果在str1中没有找到str2,返回的是char *类型的空指针,
如果在str1中找到了str2,并且找到了多次,那它只返回第一次出现的地址

在这里插入图片描述
代码演示:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[] = "abcdebcdf";
	char arr2[] = "bcd";

	char* p = strstr(arr1, arr2);
	if (p == NULL)
	{
		printf("找不到\n");
	}
	else
	{
		printf("%s\n", p);
	}
	return 0;
}

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

多次出现返回的是第一次出现的位置

与其相似的函数还有strchr
在这里插入图片描述
strstr的模拟实现
在这里插入图片描述

s1和s2不相等时,让s1往后走一步,找到与其相等的位置,用s1和s2这两个指针在维护字符串,不用str1和str2这两个指针(以防指针在找相等的字符串时走太远而记不住地址,不知道回归到哪里)
创建 cp用来记住匹配成功的地址

代码演示:

#include <stdio.h>
#include <string.h>
char* my_strstr(const char* str1, const char* str2)
{
	char* s1 = NULL;
	char* s2 = NULL;
	char* cp = (char*)str1;

	while (*cp)
	{
		s1 = cp;
		s2 = (char*)str2;
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')//说明字符串已经被查找完了
		{
			return cp;
		}
		cp++;//当s1不等于s2时,s1向后走,直到找到与s2相等的字符
	}
	return NULL;//把s1字符串遍历完也没有找到返回NULL
}
int main()
{
	char arr1[] = "abcdebcdf";
	char arr2[] = "bcd";

	char* p = my_strstr(arr1, arr2);
	if (p == NULL)
	{
		printf("找不到\n");
	}
	else
	{
		printf("%s\n", p);
	}
	return 0;
}

画图理解:
在这里插入图片描述
运行结果:
在这里插入图片描述

关于字符函数和字符串函数的讲解七七就介绍到这里了,我们下篇再见。如果这篇文章对大家有帮助,请佬佬们点个赞再走吧!如果发现什么问题,欢迎评论区留言!
在这里插入图片描述

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

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

相关文章

【洛谷刷题】蓝桥杯专题突破-深度优先搜索-dfs(9)

目录 写在前面&#xff1a; 题目&#xff1a;P1025 [NOIP2001 提高组] 数的划分 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述&#xff1a; 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 解题思路&#xff1a; 代…

【数据结构】哈希表

目录 1、哈希表 1.1 哈希表的简介 1.2 降低哈希冲突率 1.3 解决哈希冲突 1.3.1 闭散列 1.3.2 开散列&#xff08;哈希桶&#xff09; 1、哈希表 1.1 哈希表的简介 假设我们目前有一组数据&#xff0c;我们要从这组数据中找到指定的 key 值&#xff0c;那么咱们目…

【Java集合面试宝典】HashMap的put流程和特性?HashMap的扩容机制?原理— day08

目录 数组和链表分别适用于什么场景&#xff0c;为什么&#xff1f; 数组 链表 List和Set的区别 List和Map、Set的区别 HashMap 、HashTable 和TreeMap有什么区别&#xff1f; hashmap的特性 HashMap和HashTable有什么区别&#xff1f;&#xff08;必会&#xff09; J…

【数据结构】树的介绍

文章目录前言树的概念及结构树的概念树的表示树在实际中的运用二叉树的概念及结构二叉树的概念现实中的二叉树特殊的二叉树二叉树的性质二叉树的储存结构顺序存储链式存储写在最后前言 &#x1f6a9;本章给大家介绍一下树。树的难度相对于前面的数据结构来说&#xff0c;又高了…

ESP32设备驱动-HDC1080温度湿度传感器驱动

HDC1080温度湿度传感器驱动 文章目录 HDC1080温度湿度传感器驱动1、HDC1080介绍2、硬件准备3、软件准备4、驱动实现1、HDC1080介绍 HDC1080 是一款集成温度传感器的数字湿度传感器,可在极低功耗下提供出色的测量精度。 HDC1080 在很宽的电源范围内工作,是一种低成本、低功耗…

“提效”|教你用ChatGPT玩数据

ChatGPT与数据分析&#xff08;二&#xff09; 上文给简单聊了一下为什么ChatGPT不能取代数据分析师&#xff0c;本文我们来深入感受一下如何让GPT帮助数据分析师“提效”。 场景一&#xff1a;SQL取数 背景&#xff1a;多数数据分析师都要用SQL语言从数据库中提取数据&#x…

ctfshow web入门 命令执行29-33

1.web29eval()函数是把所有字符串当作php代码去执行&#xff0c;这题过滤了flag,使用通配符绕过过滤应该要注意文件中没有重名的文件&#xff0c;或一部分是一样的文件payload:cecho%20nl flag.php; #官方解法&#xff0c;反引号表示执行系统命令&#xff0c;nl为linux系统命令…

springboot智慧外贸平台

053-springboot智慧外贸平台演示录像2022开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff…

干货:浅谈主数据管理项目建设思路

“主数据是数据之源&#xff0c;是数据资产管理的核心&#xff0c;是信息系统互联互通的基石&#xff0c;是信息化和数字化的重要基础。 ——《主数据管理实践白皮书》” 近期&#xff0c;国家印发《数字中国建设整体布局规划》&#xff0c;提出数字中国建设的整体框架…

I2C协议简介 Verilog实现

I2C协议 IIC 协议是三种最常用的串行通信协议&#xff08;I2C&#xff0c;SPI&#xff0c;UART&#xff09;之一&#xff0c;接口包含 SDA&#xff08;串行数据线&#xff09;和 SCL&#xff08;串行时钟线&#xff09;&#xff0c;均为双向端口。I2C 仅使用两根信号线&#xf…

Django 实现瀑布流

需求分析 现在是 "图片为王"的时代&#xff0c;在浏览一些网站时&#xff0c;经常会看到类似于这种满屏都是图片。图片大小不一&#xff0c;却按空间排列&#xff0c;就这是瀑布流布局。 以瀑布流形式布局&#xff0c;从数据库中取出图片每次取出等量&#xff08;7 …

Educational Codeforces Round 145 (Rated for Div. 2) (A~E)

Problem - B - Codeforces 思路&#xff1a; 我们选择长度后&#xff0c;其特定长度会构成一个正方形&#xff0c;因为点与点距离大于1&#xff0c;所以偶数的正方形里面只能包含偶数的正方形&#xff0c;奇数的包含奇数。计算每个长度容纳最大点数&#xff1a; 发现cnt[0]1,…

WPF毛笔字实现过程

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

Python中生产者消费者模型

Python生产者消费者模型 一、消费模式 生产者消费者模式 是Controlnet网络中特有的一种传输数据的模式。用于两个CPU之间传输数据&#xff0c;即使是不同类型同一厂家的CPU也可以通过设置来使用。 二、传输原理 类似与点对点传送&#xff0c;又略有不同&#xff0c;一个生产…

能把爬虫讲的这么透彻的,没有20年功夫还真不行【0基础也能看懂】

前言 可以说很多人学编程&#xff0c;不玩点爬虫确实少了很多意思&#xff0c;不管是业余、接私活还是职业爬虫&#xff0c;爬虫世界确实挺精彩的。 今天来给大家浅谈一下爬虫&#xff0c;目的是让准备学爬虫或者刚开始起步的小伙伴们&#xff0c;对爬虫有一个更深更全的认知…

chatGPT爆火,什么时候中国能有自己的“ChatGPT“

目录 引言 一、ChatGPT爆火 二、中国何时能有自己的"ChatGPT" 三、为什么openai可以做出chatGPT? 四、结论 引言 随着人工智能技术的不断发展&#xff0c;自然语言处理技术也逐渐成为了研究的热点之一。其中&#xff0c;ChatGPT作为一项领先的自然语言处理技术…

【软件测试】基础知识第一篇

文章目录一. 什么是软件测试二. 测试和调试的区别三. 什么是测试用例四. 软件的生命周期五. 软件测试的生命周期一. 什么是软件测试 软件测试就是验证软件产品特性是否满足用户的需求。 那需求又是什么呢&#xff1f;在多数软件公司&#xff0c;会有两种需求&#xff0c;一种…

【vue3】小小入门介绍

⭐【前言】 首先&#xff0c;恭喜你打开了一个系统化的学习专栏&#xff0c;在这个vue专栏中&#xff0c;大家可以根据博主发布文章的时间顺序进行一个学习。博主vue专栏指南在这&#xff1a;vue专栏的学习指南 &#x1f973;博主&#xff1a;初映CY的前说(前端领域) &#x1f…

python自动发送邮件,qq邮箱、网易邮箱自动发送和回复

在python中&#xff0c;我们可以用程序来实现向别人的邮箱自动发送一封邮件&#xff0c;甚至可以定时&#xff0c;如每天8点钟准时给某人发送一封邮件。今天&#xff0c;我们就来学习一下&#xff0c;如何向qq邮箱&#xff0c;网易邮箱等发送邮件。 一、获取邮箱的SMTP授权码。…

new动态内库管理库学习

new文件是动态内存管理库的一部分&#xff0c;特别提供低层内存管理特性。 它包括bad_alloc, bad_array_new_length&#xff0c;nothrow_t&#xff0c;align_val_t类nothrow常量&#xff0c;以及函数 operator newoperator new[],operator deleteoperator delete[],get_new_han…