test16——0227(几种字符串操作函数和内存函数)

头文件:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stddef.h>  // size_t头文件包含

1.实现strcpy

char* my_strcpy(char* str1, char const *str2) {
	// 断言判定 str1 和 str2 非空
	assert(str1 != NULL);
	assert(str2 != NULL);

	while (*str2 != '\0') {
		*str1 = *str2;
		str1++;
		str2++;
	}
	return str1;
}

2.实现strcat             (使用到自己写的strcpy)

char* my_strcat(char* str1, const char* str2) {
	// 断言判定 str1 和 str2 非空
	assert(str1 != NULL);
	assert(str2 != NULL);
	str1 += strlen(str1);		// 将指针挪向第一个字符串的 '\0' 处
	my_strcpy(str1, str2);		// 将第二个字符串直接copy过来

	return str1;
}

3.实现strstr

char* my_strstr(char* str1, const char* str2) {
	//					Hello			llo
	//		
	
	// 断言判定 str1 和 str2 非空
	assert(str1 != NULL);
	assert(str2 != NULL);
	int i = 0, j = 0;
	// 用变量 i 遍历 str1, j 遍历 str2
	while (str1[i] != '\0') {
		
		while (str2[j] == str1[i]) {
		// 如果两个字符相等,都向后挪一位
			i++;
			j++;
		}
		
		if (str2[j] == '\0') {
			// 在str1中找到str2子串
			return str1 + i-j;    //将相等的第一个元素记录下来方便进行回滚
		}
		if (str1[i] == '\0') {
			// str1 结束,说明
			return NULL;
		}
		i++;
	}
	return NULL;
}


4.实现strchr

int my_strchr(char* str, char seek) {
	assert(str != NULL);
	int i = 0;
	while (*str != '\0') {
		if (str[i] == seek) {
			break;
		}
		i++;
	}
	return i;
}

5.实现strcmp

int my_strcmp(char* str1, const char* str2) {
	assert(str1 != NULL);
	assert(str2 != NULL);
	int count = 0;
	int i = 0;  // 控制循环
	while (str1[i] != '\0' && str2[i] != '\0') { 
		count += str1[i] - str2[i];
		if (str1[i] != str2[i])  // if 放在 count 自增后面 否则,count值为0
			break;
		i++;
	}
	return count;   //count = 0 表示全等
}

6.实现memcpy

void* my_memcpy(void* dest, const void* src, size_t n) {
	// sizeof(size_t) = 8
	assert(dest != NULL);
	assert(src != NULL);
	char* pde = (char*)dest;
	char* ps = (char*)src;
	int i = 0;
	while (n--) {
		if (ps[i] == '\0') {
			break;
		}
		pde[i] = ps[i];
		i++;
	}
	pde[i] = '\0';
	return (char*)dest;
}


7.实现memmove

//memmove用于拷贝字节,如果目标区域和源区域有重叠的话,
//memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,
//但复制后源内容会被更改。
//当目标区域与源区域没有重叠则和memcpy函数功能相同。
void* my_memmove(void* dest, const void* src, size_t n) {
	assert(dest != NULL);
	assert(src != NULL);
	char* pde = (char*)dest;
	char* ps = (char*)src;
	//  dest < src || (char*)dest >= (char*)src + count
	//  目标区域与原区域未重叠(不影响复制)
	if (dest < src || (char*)dest >= (char*)src + strlen(src) - 1) {
		my_memcpy(pde, ps, n);
	}
	//  目标区域与原区域重叠(影响复制)
	else {
		//char* tmp = ps;
		pde[n] = '\0'; // 手动添加'\0'
		while (n--) {
			// 从后往前复制
			pde[n] = ps[n];
		}
	}
	return pde;
}
// 调用函数my_memmove函数
// 需要注意: 正常情况和内存覆盖情况不能同时运行
int main() {
	char arr[1024] = "ABCDEFGHIJKLMN";  // 14
	int choice = 0;
	scanf("%d", &choice);   // 输入1表示正常情况
	if (choice == 1) {	// 正常情况
		my_memmove(arr, arr+2, 2);
		printf("%s\n", arr);
	}
	else{	// 内存覆盖情况
		my_memmove(arr + 8, arr, 5);
		printf("%s\n", arr + 8);
	}

	
	system("pause");
	return 0;
}

      字符串与内存函数的实现,在传参的时候要先进行断言检查指针是否为空。

ps:可以使用指针下标的方式进行,尽量不要使用指针的运算。

猜你喜欢

转载自blog.csdn.net/Q_feifeiyu/article/details/87976681