模拟实现strcpy 、strcat 、strstr 、strchr 、strcmp 、memcpy 、memmove

//1.实现strcpy (字符串拷贝)
#include<stdio.h>
#include<windows.h>
#include<assert.h>
char *my_strcpy(char*dest,const char * src)
{
assert(dest);
assert(src);
while (*dest = *src)
{
dest++;
src++;
}
return dest;
}
int main()
{
const char *str = "abcdef";
char buf[32] = { 0 };
my_strcpy(buf, str);
printf("%s", buf);
system("pause");
return 0;
}


//2.实现strcat(字符串拼接)
#include<stdio.h>
#include<windows.h>
#include<assert.h>
//#pragma warning(disable:4996)
char *my_strcat(char*dest, char * src)
{
assert(dest);
assert(src);
while (*dest)
{
dest++;
}
while (*dest = *src)
{
dest++;
src++;
}
return dest;
}
int main()
{
char str[32] = "abcdef";
//int size = sizeof(str) / sizeof(str[0]);
char buf[32] = "1123456";
my_strcat(str, buf);
printf("%s\n", str);
system("pause");
return 0;
}


//3.实现strstr(srtstr(str1,str2)函数用于判断字符串str2是否是str1的子串,如果是返回str1从子串部分的所有)
#include<stdio.h>
#include<windows.h>
#include<assert.h>
#include<string.h>
//#pragma warning(disable:4996)
char *my_strstr(const char *dest,const char *src)
{
assert(dest);
assert(src);
char *cp = NULL;
char *subsrc = NULL;
char *p = NULL;
p = dest;//将dest的首元素地址给p
while (*p){
cp = p;
subsrc = src;
while (*cp&&*subsrc&&(*cp == *subsrc))//找相同部分
{
cp++;
subsrc++;
}
if (*subsrc == '\0')//找到了
{
return p;
}
if (*cp == '\0')//表示没有子串
{
break;
}
p++;
}

return NULL;
}
int main()
{
const char str[32] = "520iloveyoudwh";
const char buf[32] = "loveyou";
char *p;
p=my_strstr(str, buf);
printf("%s\n", p);
system("pause");
return 0;
}
 
 
//4.实现strchr(函数原型:extern char *strchr(char *str,char character)
/*参数说明:str为一个字符串的指针,character为一个待查找字符。

所在库名:#include <string.h>

函数功能:从字符串str中寻找字符character第一次出现的位置。

返回说明:返回指向第一次出现字符character位置的指针,如果没找到则返回NULL。

其它说明:还有一种格式char *strchr(const char *string, int c),这里字符串是以int型给出的。
)*/
/*#include<stdio.h>
#include<windows.h>
#include<assert.h>
#include<string.h>
#pragma warning(disable:4996)
char *my_strchr(const char *dest, const char src)
{
assert(dest);
while (*dest)
{
if(*dest == src)
{
return dest;
}
dest++;
}

return NULL;
}
int main()
{
const char str[32] = "520iloveyoudwh";
const char buf ='l';
char *p;
p =my_strchr(str, buf);
printf("%s\n", p);
system("pause");
return 0;
}*/


//5.实现strcmp(strcmp函数是C/C++中基本的函数,它对两个字符串进行比较,然后返回比较结果,函数形式如下:
/*int strcmp(const char* str1, const char* str2);
其中str1和str2可以是字符串常量或者字符串变量,返回值为整形。返回结果如下规定:
① str1小于str2,返回负值或者 - 1(VC返回 - 1);                    by wgenek 转载请注明出处
② str1等于str2,返回0;
③ str1大于str2,返回正值或者1(VC返回1);
strcmp函数实际上是对字符的ASCII码进行比较,实现原理如下:首先比较两个串的第一个字符,若不相等,则停止比较并得出两个ASCII码大小比较的结果;如果相等就接着 比较第二个字符然后第三个字符等等。无论两个字符串是什么样,strcmp函数最多比较到其中一个字符串遇到结束符'/0'为止,就能得出结果。
strcmp算法的可以有多种,不过我觉的可以把这么多算法分为两种,一种是利用减法运算判断结果,另一种是利用比较运算( == )得出结果。
)*/
#include<stdio.h>
#include<windows.h>
#include<string.h>
#include<assert.h>
int my_strcmp( const char*src, const char*dst)
{
int ret = 0;
int res = 0;
//判断长度
while (!(ret = *(unsigned char*)src - *(unsigned char*)dst) && *dst)//首先比较两个串的第一个字符,若不相等,则停止比较并得出两个ASCII码大小比较的结果;
{
++src;
++dst;
}
if (ret < 0)
{
res= -1;//后者大
}
else if (ret>0)
{
res = 1;//前者大
}
else{
res = 0;//相等
}
return res;

}
int main()
{
const char *str1 = "ljj520dwh";
const char*str2 = "dwh520ljjforever";
int ret;
ret=my_strcmp(str1, str2);
printf("%d\n", ret);
system("pause");
return 0;
}


//6.实现memcpy(函数原型:void *memcpy(void*dest, const void *src, size_t n);

/*用法:#include<string.h>

功能:从源src所指的内存地址的起始位置开始,拷贝n个字节的数据到目标dest所指的内存地址的起始位置中。

说明:

1)src和dest所指内存区域不能重叠,函数返回指向dest的指针。如果src和dest以任何形式出现了重叠,它的结果是未定义的。

2)与strcpy相比,memcpy遇到’\0’不结束,而且一定会复制完n个字节。只要保证src开始有n字节的有效数据,dest开始有n字节内存空间就行。

3)如果目标数组本身已有数据,执行memcpy之后,将覆盖原有数据(最多覆盖n个)。

如果要追加数据,则每次执行memcpy()后,要将目标地址增加到要追加数据的地址。

4)source和destin都不一定是数组,任意的可读写的空间均可。
)*/
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<windows.h>
void* my_memcpy(void* dest, const void* src, int n)//因为memcpy是内存拷贝函数,所以必须什么类型都能接收,所以此处用void*做参数类型和返回值类型
{
	assert(dest != NULL);
	assert(src != NULL);
	char* ret = dest;//因为dest在循环体中不断发生变化,所以将dest的地址存放在指针变量ret中,此后ret就随着dest进行变化,但dest不会随着ret进行变化,最后函数返回ret的值
	while (n--)
	{
		*(char*)dest = *(const char*)src;//void类型不能进行解引用操作,所以要进行强制类型转化,因为此处n指的是字节数,需要一个字节一个字节拷贝,所以强制类型转化为char*。
		++(char*)dest;//void*类型不能进行++操作,所以要进行强制类型转化,如果是后置++,那么强制类型转化先对dest进行,所以要进行前置++
		++(char*)src;
	}
	return ret;
}

//arr1打印输出函数
void print(int arr1[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr1[i]);
	}
	printf("\n");
}

int main()
{
	char* str1[10] = { 0 };
	char* str2 = "abcdefg";
	char* ret = NULL;
	ret = my_memcpy(str1, str2, 5);//n代表的是字节数
	printf("%s\n", ret);

	int arr1[10] = { 0 };
	int arr2[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	my_memcpy(arr1, arr2, 40);//此处n是字节数,40个字节也就是10个int型值
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	print(arr1, sz);
	system("pause");
	return 0;
}


//7.实现memmove(memmove() 用来复制内存内容,其原型为:
/*void * memmove(void *dest, const void *src, size_t num);
memmove() 与 memcpy() 类似都是用来复制 src 所指的内存内容前 num 个字节到 dest 所指的地址上。
不同的是,memmove() 更为灵活,当src 和 dest 所指的内存区域重叠时,memmove() 仍然可以正确的处理,
不过执行效率上会比使用 memcpy() 略慢些。)*/
#include<stdio.h>  
#include<string.h>  
#include<assert.h>  
#include<windows.h>
void *my_memmove(void *dest, const void*src, int count)
{
	int i = 0;
	char *pdest = (char*)dest;
	void *pret = dest;
	const char*psrc = (const char*)src;//强制转换  
	assert(src);
	assert(dest);
	if ((pdest > psrc) && (pdest < psrc + count))      //重叠  
	{
		while (count--)
		{
			*(pdest + count) = *(psrc + count);
		}
	}
	else                                               //不重叠  
	{
		while (count--)
		{
			*pdest++ = *psrc++;
		}
	}
	return pret;
}
int main()
{
	int i = 0;
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	my_memmove(arr +4, arr,  3*sizeof(int));
	for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d\n", arr[i]);
	}
	system("pause");
	return 0;
}


猜你喜欢

转载自blog.csdn.net/pigdwh/article/details/80386852
今日推荐