Simulation implementation of string processing functions and memory processing functions

Hehe, this series is coming out today.

Table of contents

1. String processing function​

1. Three forms of strlen

1. Counter

2. Recursion

3. Pointer - Pointer

2. strcmp simulation implementation

3. strcat simulation implementation

4. strcpy simulation implementation

5. strstr simulation implementation

6. strtok implementation

2. Memory processing function

1. Simulation and implementation of memcpy

2. Simulate the implementation of memmove


1. String processing functions

 The above are several common string processing functions. The purpose of our simulation implementation is to write it ourselves when we cannot use such functions in the future, mainly to learn how to do it.

1. Three forms of strlen

1. Counter

#define _CRT_SECURE_NO_WARNINGS 1
//计数器
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
	int count = 0;
	assert(dest);
	while (*dest++) {
		count++;
	}
	return count;

}
int main() {
	char arr[] = "hello";

	printf("%d",my_strlen(arr));


	return 0;
}

2. Recursion

#define _CRT_SECURE_NO_WARNINGS 1
//递归
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
	assert(dest);
	if (!* dest)
		return 0;
	return 1 + my_strlen( dest + 1);
}
int main() {
	char arr[] = "hello";

	printf("%d", my_strlen(arr));


	return 0;
}

3. Pointer - Pointer

#define _CRT_SECURE_NO_WARNINGS 1
//指针-指针
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
	assert(dest);
	const char* p = dest;
	while (*p) {
		p++;
	}
	return p - dest;

}
int main() {
	char arr[] = "hello";

	printf("%d", my_strlen(arr));


	return 0;
}

2. strcmp simulation implementation

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* arr1, const char* arr2) {
	assert(arr1 && arr2);
	while (*arr1 == *arr2 ) {
		arr1++;
		arr2++;
		if(*arr2=='\0')
		return 0;
	}
	return *arr1 - *arr2;
}

int main() {

	char arr1[20] = "hello ";
	char arr2[] = "world";
	int ret=my_strcmp(arr1, arr2);
	if (ret == 0) {
		printf("arr1=arr2");
	}
	if (ret < 0) {
		printf("arr1<arr2");
	}
	if (ret > 0) {
		printf("arr1>arr2");
	}

	return 0;
}

3. strcat simulation implementation

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* res) {
	assert(dest && res);
	char* p = dest;
	while (*dest) {
		dest++;
	}
	while (*dest++=*res++) {
		;
	}

	return p;
}

int main() {
	char arr1[20] = "hello ";
	char arr2[] = "world ";

	printf("%s\n", my_strcat(arr1, arr2));

	return 0;
}

4. strcpy simulation implementation

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest,char * src) {
	assert(dest && src);
	char* p = dest;
	while (*dest++ = *src++);
	return p;
}
int main() {
	char arr1[20] = "hello ";
	char arr2[] = "world";
	
	printf("%s\n",my_strcpy(arr1, arr2) );

	return 0;
}


5. strstr simulation implementation

#define _CRT_SECURE_NO_WARNINGS 1
//模拟实现strstr函数
//在arr1中找是否包含arr2数组
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2) {
	assert(str1 && str2);
	const char* s1 = NULL;
	const char* s2 = NULL;
	//如果*str2=0;则需要返回str1的地址,所以str1的地址不能变
	char* cp = str1;

	if (*str2 == '\0') {
		//由于我定义的是const类型的,所以返回时需要强制转换为char*类型
		return (char*)str1;
	}

	while (*cp) {
		s1 = cp;
		s2 = str2;
		while (*s1 && *s2 && (*s1 == *s2)) {
			s1++;
			s2++;
		}
		//这里必定是由上面的while中跳出来的,因为上面已经筛选过了,当*s2结束,返回当前cp的地址
		if (*s2 == '\0')
			return (char*)cp;
		cp++;
	}
	//要么是找不到,*s2为0,程序直接结束,要么也是找不到,直到*cp为0,返回空指针,要么因为*s1为0,返回空指针
	return NULL;
}
int main() {
	char arr1[] = "abdjkhgio";
	char arr2[] = "jk";

	char* ret = my_strstr(arr1, arr2);
	if (ret == NULL) {
		printf("No found!");
	}
	else {
		printf("%s", ret);
	}

	return 0;
}

6. strtok implementation

#define _CRT_SECURE_NO_WARNINGS 1
//strtok函数实现
#include<stdio.h>
#include<string.h>
int main() {
	char arr[] = "[email protected]";
	char* p = "@.";

	char tmp[20] = {0};

	strcpy(tmp, arr);

	char* ret = NULL;
    //strtok的返回值是遇到标志的地址,所以之后都是从null开始,函数将标志改为了\0
	for (ret = strtok(tmp, p); ret; ret = strtok(NULL, p)) {
		printf("%s\n", ret);
	}

	return 0;
}

2. Memory processing function

1. Simulation and implementation of memcpy

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
//num指的是字节长度
void* my_memcpy(void* dest, const void* src, size_t num) {
	void* ret = dest;
	assert(dest && src);
	//这个函数是一个字节一个字节的传,为了能让多种数据都能使用该函数,强制转换为char*类型
	while (num--) {
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
		//*(char*)dest++=*(char*)src++;
		//这种方法是错的 ,解引用强制转换了之后,在进行++操作时,强制转换的作用已经不存在了
	}

	return ret;
}
int main() {
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 0 };
	//arr2要够长,不然容易栈溢出。
	my_memcpy(arr2, arr1, 20);

	for(int i=0;i<5;i++)
	printf("%d\n", *(arr2+i));
	
	return 0;
}

2. Simulate the implementation of memmove

#define _CRT_SECURE_NO_WARNINGS 1
#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 arr1[] = { 1,2,3,4,5,6,7,8,9,10 };

	my_memmove(arr1 + 2, arr1, 20);


	return 0;
}

Precautions:

 The memcpy function should copy non-overlapping memory

The memmove function can handle memory overlap situations.

According to the requirements of C language, memcpy can only copy non-overlapping memory, but in VS, it can copy overlapping memory.

Guess you like

Origin blog.csdn.net/m0_63309778/article/details/121855286