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语言字符串函数及内存函数的模拟实现和原理

目录

?一、求字符串长度

1.strlen()函数

1.函数功能

2.函数原形

3.模拟实现

二、长度不受限制的字符串操作函数

1.strcpy()函数

1.函数功能

2.函数原形

3.模拟实现

2.strcat()函数

1.函数功能

2.函数原形

3.模拟实现

3.strcmp()函数

1.函数功能

2.函数原形

3.模拟实现

三、长度受限制的字符串操作函数

1.strncpy()函数

1.函数功能

2.函数原型

3.模拟实现

2.strncat()函数

1.函数功能

2.函数原形

3.模拟实现

3.strncmp()函数

1.函数功能

2.函数原形

3.函数模拟

八、字符串查找

1.strstr()函数

1.函数功能

2.函数原形

3.模拟实现

2.strtok()函数

1.函数功能

2.函数原形

3.实现原理

四、错误信息报告

1.strerror()函数

1.函数功能

2.函数原形

3.实现原理

五、内存操作函数

1.memcpy()函数

?1.函数功能

2.函数原形

3.模拟实现

2.memmove()函数

1.函数功能

2.函数原形

3.模拟实现

3.memset()函数

1.函数功能

2.函数原形

3.模拟实现

4.memcmp()函数

1.函数功能

2.函数原形

3.模拟实现


?一、求字符串长度

1.strlen()函数

1.函数功能

? ? 计算字符串长度的函数,返回类型是size_t,即无符号整型。

2.函数原形

? ?size_t strlen(const char* str);

3.模拟实现

代码:

//模拟实现strlen()函数
unsigned int my_strlen(const char* str)
{
    char* tmp = str;
	int len = 0;
	while (*tmp)
	{
		len++;
		tmp++;
	}
	return len;
}

二、长度不受限制的字符串操作函数

1.strcpy()函数

1.函数功能

? ? 拷贝字符串(包括'\0'),读到'\0'就停止拷贝。

2.函数原形

? ?char * strcpy ( char * destination, const char * source );

3.模拟实现

代码:

//模拟实现strcpy()函数
//将str2拷贝到str1中
char* my_strcpy(char* str1, const char* str2)
{
	char* tmp = str1;
	while (*str2)
	{
		*str1 = *str2;
		str1++;
		str2++;
	}
	*str1 = '\0';
	return tmp;
}

2.strcat()函数

1.函数功能

? ? 实现字符串的连接。

2.函数原形

char* strcat(char* destination, const char* source);

3.模拟实现

代码:

//模拟实现strcat()函数
char* my_strcat(char* str1, const char* str2)
{
	char* tmp = str1;
	while (*++str1);//循环结束后*str1是'\0'
	while (*str2)
	{
		*str1 = *str2;
		str1++;
		str2++;
	}
    *str1++ = '\0';
	return tmp;
}

3.strcmp()函数

1.函数功能

? ? 比较两个字符串的大小。

? ? 比较的是两个字符串对应字符的ASCII码值,第一个字符串字符大于第二个字符串中对应字符时函数返回大于0的数,小于时返回小于0的数,等于时返回0。

2.函数原形

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

3.模拟实现

代码:

//模拟实现strcmp()函数
int my_strcmp(const char* str1, const char* str2)
{
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
		{
			return 0;
	    }
		str1++;
		str2++;
	}
	return (*str1 - *str2);
}

三、长度受限制的字符串操作函数

1.strncpy()函数

1.函数功能

? 拷贝字符串(前n个字符(不包括'\0')),将前n个字符拷贝完成后,将目标空间的第n+1个字符置为'\0',以终止拷贝。

2.函数原型

? ?char * strncpy ( char * destination, const char * source, size_t num );

3.模拟实现

代码:

//模拟实现strncpy()函数
char* my_strncpy(char* str1, const char* str2,unsigned int n)
{
	char* tmp = str1;
	while (n)
    {
		*str1 = *str2;
		str1++;
		str2++;
        n--;
	}
	*str1 = '\0';
	return tmp;
}

2.strncat()函数

1.函数功能

? ? 将源字符串的前n个字符连接到目标字符串,其后加'\0'结束字符串。

2.函数原形

? ??char * strncat ( char * destination, const char * source, size_t num );

3.模拟实现

代码:

//模拟实现strcat()函数
char* my_strcat(char* str1, const char* str2,unsigned int n)
{
	char* tmp = str1;
	while (*++str1);
	while (n)
	{
		*str1 = *str2;
		str1++;
		str2++;
        n--;
	}
    *str1++ = '\0';
	return tmp;
}

3.strncmp()函数

1.函数功能

? ? 比较两个字符串的前n个字符。

2.函数原形

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

3.函数模拟

代码:

//模拟实现strcmp()函数
int my_strcmp(const char* str1, const char* str2,unsigned int n)
{
	while (*str1 == *str2 && n)
	{
		if (*str1 == '\0')
		{
			return 0;
		}
		str1++;
		str2++;
        n--;
	}
	return (*str1 - *str2);
}

八、字符串查找

1.strstr()函数

1.函数功能

? ? 找到字符串中的子字符串,并返回第一次出现的子字符串的首地址。

2.函数原形

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

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

3.模拟实现

代码:

//模拟实现strstr()函数
char* my_strstr(char* str1, const char* str2)
{
	char* s1 = str1;
	char* s2 = str2;
	char* p1 = s1;
	char* p2 = s2;
	while (*p1)
	{
		while (*s1 == *s2 && *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return p1;
		else
		{
			p1++;
			s1 = p1;
			s2 = p2;
		}
	}
	return NULL;
}

2.strtok()函数

1.函数功能

? ? 截断字符串(按标识符截断)。

2.函数原形

? ?char * strtok ( char * str, const char * delimiters );

3.实现原理

代码:

//strtok()函数的应用
int main()
{
	char arr[] = "http@qq.com";
	char buf[200] = { 0 };
	strcpy(buf, arr);//buf[200]="http@qq.com"
	const char* p = "@.";//标识符
	char* str = NULL;

	for (str=strtok(buf, p); str!=NULL; str=strtok(NULL, p))
	{
		printf("%s\n", str);
	}

	return 0;
}

运行结果:

解释:

? ? strtok()函数传参的时候,第一个参数为截断字符串的起始地址。第一次传参的时候传所需截断字符串的首地址;从第二次开始,因为第一次截断时strtok()?记住了标识符的下一个字符的地址,所以只需传空指针NULL;如需截断另一个新的字符串,只需将新字符串的地址传给第一个参数即可。

四、错误信息报告

1.strerror()函数

1.函数功能

? ? 获取指向错误消息字符串的指针(把错误码转化为错误信息)。

2.函数原形

char * strerror ( int errnum );

3.实现原理

代码:

#include <stdio.h>
#include <string.h>
#include <errno.h>
//strerror
//把错误码转换成错误信息
int main()
{
    printf("%s\n", strerror(0));
	printf("%s\n", strerror(1));
	printf("%s\n", strerror(2));
	printf("%s\n", strerror(3));
	printf("%s\n", strerror(4));
    printf("%s\n", strerror(5));

    //错误码记录到错误码的变量中
	//errno - C语言提供的全局的错误变量
    printf("%s\n",strerror(errno));
    return 0;
}

运行结果:

五、内存操作函数

1.memcpy()函数

?1.函数功能

? ?内存拷贝(一般编译器不支持目标空间和被拷贝的部分有重叠),因拷贝内容的类型不确定,故以单个字节为单位进行拷贝,返回目标空间的起始地址。

2.函数原形

? ??void * memcpy ( void * destination, const void * source, size_t num );

3.模拟实现

代码:

#include <stdio.h>
#include <assert.h>
//模拟实现memcpy()
//memcpy()函数的功能因编译器而异,大部分编译器不能处理有重叠的情况,此处不予考虑
void* my_memcpy(void* destination, const void* source, unsigned int n)
{
	assert(destination && source);
    //为了代码的可移植性,因为拷贝对象的大小不确定,所以以单个字节为单位拷贝
	char* src = (char*)source;
	char* des = (char*)destination;

	while (n)
	{
		//从前往后拷贝
		*des = *src;
		des++;
		src++;
		n--;
	}

	return destination;//返回目的空间的首地址,方便链式访问	    
}

函数原理:

? ? void*可以接受任意类型变量的地址,因为变量大小的不确定性,将指针强转为char*(指针类型决定解引用可以访问的空间大小,char*解引用访问一个字节大小的空间),然后一个字节一个字节的拷贝。

2.memmove()函数

1.函数功能

? ? 内存拷贝(与memcpy()函数相似,memmove()函数能处理目标空间和被拷贝空间有重叠的情况)。

2.函数原形

? ??void * memmove ( void * destination, const void * source, size_t num );

3.模拟实现

代码:

#include <stdio.h>
#include <assert.h>
//模拟实现memmove()
void* my_memmove(void* destination,const void* source,unsigned int n)//n为拷贝的字节数
{
	assert(destination && source);
	//为了代码的可移植性,因为拷贝对象的大小不确定,所以以单个字节为单位拷贝
	char* src = (char*)source;
	char* des = (char*)destination;

	if (src < des && src + n - 1 > des)
	{
		des = des + n - 1;
		src = src + n - 1;
		//重叠且source在前:从后往前拷贝
		for (int i = 0;i < n;i++)
		{
			*des = *src;
			des--;
			src--;
		}
	}
	else
	{
		//没有重叠的空间或者重叠但source在后:从前往后拷贝
		for (int i = 0;i < n;i++)
		{
			*des = *src;
			des++;
			src++;
		}
	}
	return destination;//方便链式访问
}

? ?函数原理:

? ? 处理目标空间和被拷贝空间有重叠的时候有两种情况,第一种,目标空间在前,被拷贝空间在后,从前往后拷贝(与不重叠的情况拷贝顺序相同);第二种,目标空间在后,被拷贝空间在前,从后往前拷贝。

3.memset()函数

1.函数功能

? ? 将目标空间的前num个字节的空间都赋值为value。

2.函数原形

? ? void * memset ( void * ptr, int value, size_t num );

3.模拟实现

代码:

//模拟实现memset()函数
void* my_memset(void* ptr, int value, unsigned int n)
{
	char* p = (char*)ptr;
	char tmp = (unsigned char)value;
	while (n)
	{
		*p = tmp;
		p++;
		n--;
	}
	return ptr;
}

int main()
{
	char str[] = "almost every programmer should know memset!";
	my_memset(str, '-', 6);
	puts(str);
	return 0;
}

运行结果:

4.memcmp()函数

1.函数功能

? ? 比较两个内存空间内对应内容的大小,以单个字节为单位进行比较,比较两个指针指向空间前num个字节的内容,与strcmp()函数不同的是,遇到'\0'也不会停止比较。

2.函数原形

? ??int memcmp ( const void * ptr1, const void * ptr2, size_t num );

3.模拟实现

代码:

#include <stdio.h>

//模拟实现memcmp()函数
int my_memcmp(const void* ptr1, const void* ptr2, unsigned int n)
{
	char* p1 = (char*)ptr1;
	char* p2 = (char*)ptr2;

	while (*p1 == *p2)
	{
		if (n == 0)
			return 0;
		else
		{
			p1++;
			p2++;
			n--;
		}
	}
	return *p1 - *p2;
}

int main()
{
	char buffer1[] = "DWgaOtP12df0";
	char buffer2[] = "DWGAOTP12DF0";

	int n;

	n = my_memcmp(buffer1, buffer2, sizeof(buffer1));

	if (n > 0)
		printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
	else if (n < 0)
		printf("'%s' is less than '%s'.\n", buffer1, buffer2);
	else 
		printf("'%s' is the same as '%s'.\n", buffer1, buffer2);

	return 0;
}

运行结果:

这篇文章写到这里就结束啦,看到错误的话烦请指正,谢谢大家!!!

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-21 00:08:17  更:2022-09-21 00:10:42 
 
开发: 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年11日历 -2024/11/23 9:46:07-

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