IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 模拟实现C语言中常用函数 -> 正文阅读

[C++知识库]模拟实现C语言中常用函数

模拟实现C语言中常用函数

1、strlen

strlen是求字符串长度的函数

size_t strlen ( const char * str );
//1、字符串以 '\0' 作为结束标志,strlen函数返回的
//   是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。

//2、参数指向的字符串必须要以 '\0' 结束。
//3、注意函数的返回值为size_t,是无符号的

在这里插入图片描述

看到这里,我相信大家有一个疑问,那就是 str1的长度是6,str2的长度是3,所以str2的长度减str1的长度是小于0的,可是结果却是str2>str1;
那么这个时候 strlen的返回值为size_t,是无符号的这句话就特别重要了。看图片详细解释
在这里插入图片描述
因此,strlen(str2)-strlen(str1) 返回的值是4294967293,并不是-3;

//模拟实现strlen 
    #include<stdio.h>
    int count = 0;
	int test(char* ptr)
	{

		if (*ptr == 0)//递归结束条件
		{
			return 0;
		}

		return test(ptr + 1) + 1;
    //用递归法来实现

	}
	int main()
	{
		char arr[] = "abcdef";
		int len=test(arr);
		printf("%d\n", len);
		return 0;
	}

2、strcpy

char* strcpy(char* destination, const char* source )
//1、源字符串必须以 '\0' 结束。
//2、会将源字符串中的 '\0' 拷贝到目标空间。
//3、目标空间必须足够大,以确保能存放源字符串。
//4、目标空间必须可变。

strcpy是拷贝字符串的函数

char* destination:是目标空间的地址
char* source:是原字符串首元素的地址


//模拟实现strcpy

#include<stdio.h>
char* my_strcpy(char* str, const char* ptr)
{
	char* str1 = str;
	while (*str++ = *ptr++)
		//因为*的优先级大于后置++
		//所以*str++ = *ptr++可以看成下面这样
		//{
		//	*str = *ptr;
		//	str++;
		//	ptr++;
		//}
    {
		;
	}
	return str1;
}
int main()
{
	char arr[20] = { 0 };
	char name[] = "nishishei";
	//将name数组中的内容拷贝到arr数组中
	my_strcpy(arr, name);

	printf("%s\n", arr);
	return 0;
}

在这里插入图片描述

3、strcat

strcat是字符串追加函数

char * strcat ( char* destination, const char* source );
//1、源字符串必须以 '\0' 结束。
//2、目标空间必须有足够的大,能容纳下源字符串的内容。
//3、目标空间必须可修改。
    #include<stdio.h>
	char* my_strcat(char* str, char* ptr)
	{
		char* btr = str;
		while (*str != 0)
		//通过while循环找到字符串结束的位置
		{
			str++;
		}
		while (*str++ = *ptr++)
		//将我们想要追加的字符串拷贝进目标字符串
		{
			;
		}
		return btr;
	}
	int main()
	{
		char arr[] = "ni shi ";
		//初始化数组arr
		my_strcat(arr, "shei");
		//将 shei 追加给数组arr
		printf("%s\n",arr);
		return 0;
	}

4、strcmp

strcmp是比较字符串大小的函数
注意。他比较的并不是字符串长度的大小,而是一个字节一个字节的比较,比较的是字符的ASCII值

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

//1、第一个字符串大于第二个字符串,则返回大于0的数字
//2、第一个字符串等于第二个字符串,则返回0
//3、第一个字符串小于第二个字符串,则返回小于0的数字
#include<assert.h>
#include<stdio.h>
int my_strcmp(char* str, char* ptr)
{
	assert(str && ptr);
	//为了安全,防止出现空指针
	while (*str == *ptr)
	//如果字符相等,进入循环,比较下一个字符
	{
		if (*str == '\0')
		//如果两个字符串相等且有一方为'0'
		//说明这两个字符串相等,返回0;
		{
			return 0;
		}
		str++;
		ptr++;
	}
	return (*str - *ptr);
}
int main()
{
	char arr[] = "abcc";
	char name[] = "abca";
	int ret = my_strcmp(arr, name);
	if (ret < 0)
		printf("<\n");
	else if (ret > 0)
		printf(">\n");
	else
		printf("==\n");
}

5、strncpy、 strncat、 strncat

这三个函数与上面说的第2、3、4个函数并无本质区别,只是设定了特定的字符个数来执行、

char* strncpy (char * destination, 
            const char * source, size_t num );
//1、拷贝num个字符从源字符串到目标空间。
//2、如果源字符串的长度小于num,则拷贝完源字符串
//   之后,在目标的后边追加0,直到num个。

在这里插入图片描述
在这里插入图片描述

char* strncat (char* destination, 
           const char * source, size_t num );
#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;
}

在这里插入图片描述

6、strstr

1、strstr原理介绍

strstr是查找字符串函数

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

查找字符串函数是将原有的字符串的首元素地址付赋一个指针变量,然后通过指针变量来查找我们要查找的目标字符串,如果找到,那么将指针变量返回,否则返回空指针。

模拟实现strstr

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include<stdio.h>
#include<assert.h>
char* my_strstr(char* str, char* ptr)
{
	assert(str && ptr);
	char* s1 = str;
	char* s2 = ptr;
	char* p = str;
	while (*p)
	{
		s1 = p;
		s2 = ptr;
		while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (* s2 == '\0')
		{
			return p;
		}
		p++;
	}
	return NULL;
}
int main()
{
	char arr[] = "abbcdef";
	char arr1[] = "bbc";
	char* ret = my_strstr(arr, arr1);
	printf("%s\n", ret);
	return 0;
}

举个例子

2、strstr应用举例

在这里插入图片描述
在这里插入图片描述

7、strtok

strtok是字符串切割函数

1、strtok原理介绍

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 指针。

在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
#include <string.h>
int main()
{
	//char str[] = "- This, a sample string.";
	char str[] = " ni shi shei,  nihao.";

	char* pch;
	printf("Splitting string \"%s\" into tokens:\n", str);
	pch = strtok(str, " ,.-");
	while (pch != NULL)
	{
		printf("%s\n", pch);
		//第一次pch返回的是T的地址
		// 
		//第二次返回的是a的地址,因为我们没有找到
		//下一个分隔符但是遇到了空格,所以pch指向了下一个单词

		//第三次返回s
		//第四次返回s

		pch = strtok(NULL, " ,.-");
	}
	return 0;
}

在这里插入图片描述

8、strerror

strerror是一个返回错误码,所对应的错误信息的函数

char * strerror ( int errnum );

注意:必须包含头文件#include <errno.h>

9、 memcpy

1、memcpy简单介绍

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

在这里插入图片描述

2、模拟实现memcpy

void* memcpy(void* dst, const void* src, size_t count)
{
	void* ret = dst;
	assert(dst);
	assert(src);
	//防止 dst 与 src是空指针
	while (count--) 
	{
		*(char*)dst = *(char*)src;
		dst = (char*)dst + 1;
		src = (char*)src + 1;
	}
	return(ret);
}

10、memmove

1、memove简单介绍

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

在这里插入图片描述
memove可以实现字符串本身的拷贝

2、模拟实现memmove

void* memmove(void* dst, const void* src, size_t count) 
{
	void* ret = dst;
	if (dst <= src || (char*)dst >= ((char*)src + count)) 
	{
		while (count--) 
		{
			*(char*)dst = *(char*)src;
			dst = (char*)dst + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		dst = (char*)dst + count - 1;
		src = (char*)src + count - 1;
		while (count--)
	    {
			*(char*)dst = *(char*)src;
			dst = (char*)dst - 1;
			src = (char*)src - 1;
		}
	}
	return(ret);
}

如果有错误,欢迎批评指正!

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:02:42  更:2022-07-17 16:07:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/13 8:57:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码