常见字符串函数和内存函数模拟实现

目录

本章目的:

strlen模拟实现

strcmp模拟实现

strcat模拟实现

strcpy模拟实现

strstr模拟实现

strncmp模拟实现

strncat模拟实现

strncpy模拟实现

介绍strtok

介绍strerror

模拟实现memcpy

模拟实现memmove

模拟实现memcmp

最后


本章目的:

模拟实现字符串函数:strlen、strcmp、strcat、strcpy、strstr、strncmp、strncat、strncpy

介绍strtok、strerror的使用

模拟实现内存函数:memcpy、memmove、memset、memcmp

strlen模拟实现

size_t my_strlen(const char* str)
{
	assert(str);
	if (*str == '\0')
	{
		return 0;
	}
	return 1 + strlen(str + 1);
}

strcmp模拟实现

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;
}

strcat模拟实现

char* my_strcat(char* dest,const char* sour)
{
	char* ret = dest;
	assert(dest && sour);
	while (*dest)
	{
		dest++;
	}
	while (*dest++ = *sour++)
	{
		;
	}
	return ret;
}

简言:

找到目标字符串的‘\0’,然后拷贝源字符串过去(包括源字符串的结束标志),返回目标字符串的起始地址。

strcpy模拟实现

char* my_strcpy(char* dest,const char* sour)
{
	char* ret = dest;
	assert(dest && sour);
	while (*dest++=*sour++)
	{
		;
	}
	return ret;
}

strstr模拟实现

char* my_strstr(char* str,const char* substr)
{
	char* cur = str;
	assert(str && substr);
	while (*cur)
	{
		char* s1 = cur;
		char* s2 = (char*)substr;
		while (*s1 == *s2 && *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return cur;
		}
		cur++;
	}
	return NULL;
}

strncmp模拟实现

int my_strncmp(const char* str1,const char* str2,int n)
{
	assert(str1 && str2);
	while (*str1 == *str2 && n > 0)
	{
		n--;
		str1++;
		str2++;
	}
	if (n == 0)
	{
		return 0;
	}
	return *str1 - *str2;
}

strncat模拟实现

char* my_strncat(char* dest,const char* sour,int n)
{
	char* ret = dest;
	assert(dest && sour);
	while (*dest)
	{
		dest++;
	}
	while (n--)
	{
		*dest++ = *sour++;
	}
	return ret;
}

strncpy模拟实现

char* my_strncpy(char* dest,const char* sour,int n)
{
	char* ret = dest;
	assert(dest && sour);
	while (n--)
	{
		*dest++ = *sour++;
	}
	return ret;
}

介绍strtok

strtok函数可以某些符号达到分割字符串的效果

如你要从“[email protected]#apple”中提取“hello”、“world”、“name”、“apple”字符串,就可以使用strtok,其中“[email protected]”为目的字符串,“@.#”为分割符集合。

第一个参数strToken为要进行分割的字符串,第二个参数strDelimit为分割符的集合。

关于strtok的返回值

 翻译为:所有这些函数都返回一个指针,指向在strToken中找到的下一个标记。当找不到更多令牌时,它们返回NULL。每次调用都会通过将遇到的每个分隔符替换为空字符来修改strToken。

 strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。所以strtok函数会改变被操作的字符串,因此在使用strtok函数切分的字符串一般都是临时拷贝的内容
并且可修改。

strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。
如果字符串中不存在更多的标记,则返回 NULL 指针。

以下是从“[email protected]#apple”分离“hello”、“world”、“name”、“apple”的代码

介绍strerror

这个函数使用起来相对简单,根据传递的错误码打印对应的错误信息,并返回字符指针。

错误码可以是0,1,2,3,4,5,6等。

如:

 

 实际运用多数情况下与errno(一个全局变量)配套使用

errno这个全局变量会随着程序的错误自动的变动它的错误码,因此我们通常用strerror(errno)打印错误信息。

注意头文件的引用,errno的头文件是errno.h 而strerror的头文件是string.h

使用场景:

模拟实现memcpy

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

模拟实现memmove

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

相同点memmove与memcpy功能基本相同,都能进行以字节为单位拷贝内存。

不同点:memmove()能够拷贝重叠的内存、

memcpy()c标准并未要求它能完成拷贝重叠的内存。vs2019memcpy()能够拷贝重叠内存。

模拟实现memset

void* my_memset(void* dest, int c, size_t count)
{
	assert(dest);
	void* ret = dest;
	while (count--)
	{
		*(char*)dest = (char)c;
		dest = (char*)dest + 1;
	}
	return ret;
}

模拟实现memcmp

int my_memcmp(const void* str1, const void* str2,int num)
{
    assert(str1 && str2);
	while (*(char*)str1 == *(char*)str2 && num>0)
	{
		str1 = (char*)str1 + 1;
		str2 = (char*)str2 + 1;
		num--;
	}
	if (num == 0)
	{
		return 0;
	}
	else if (*(char*)str1 > *(char*)str2)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

最后

如果关于本章有什么疑问,欢迎与本人交流。

如果本章出现错误的地方,欢迎指出,本人感激不尽。

如果觉得有收获的话,欢迎点赞和评论,谢谢。

猜你喜欢

转载自blog.csdn.net/m0_62171658/article/details/123162881
今日推荐