字符串和内存函数(库函数)及其模拟总结

本文详细介绍了C语言中字符串处理函数如strlen、strcpy、strcat、strcmp等的使用和模拟实现,以及内存操作函数如memcpy、memmove、memcmp的使用方法。
摘要由CSDN通过智能技术生成

一、字符串:

注意:以下函数需包含头文件

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>

1.1 strlen的使用和模拟实现

//1.1 strlen 返回值size_t--无符号
//strlen:从字符串的开头位置依次往后面计数,
//直到遇到‘\0’停止,所计算的字符串大小为‘\0’以前的字/符所计算的值,
//最终的字符串长度不包括‘\0’
//模拟

//-1-
size_t mystrlen(const char* str)
{
	int count=0;
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}

//-2- 指针-指针
size_t mystrlen(const char* pstr)
{
	if (pstr == NULL)
		return  0;
	int count = 0;
	while (*pstr++ != '\0')
	{
		count++;
	}
	return count;
}

//-3- 递归方法
size_t mystrlen(const char* str)
{
	if (*str != '\0')
	{
		return 1 + mystrlen(str + 1);
	}
	else
		return 0;
}

int main()
{
	size_t sz = mystrlen("abc");
	printf("%u\n", sz);
	return 0;
}

1.2 strcpy的使用和模拟实现

//1.2 strcpy 字符串拷贝(覆盖)
//char* strcpy(char * destination,char * source)
//源字符串必须以'\0'结束
//会将源字符串的'\0'拷贝到目标空间
//目标空间(destination)必须足够大,以确保能存放源字符串
//目标空间必须可变

//strcpy例子
int main()
{
	char arr1[20] = "xxxxxxxxxxxxx";
	char arr2[] = "hello boy";
	char arr3[] = { 'a','b','c','d','\0'};
	strcpy(arr1, arr3);
	printf("%s\n", arr1);
	return 0;
}

//my_strcpy模拟实现
char* my_strcpy(char* dest, const char* src)
{
	//断言assert一下,确保dest和src都是指针
	assert(dest != NULL);
	assert(src != NULL);
	char* ret = dest;
	/*while (*src != '\0')
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = *src;//解决\0,得把\0加上
	*/
	while (*dest++ = *src++)
	{
		;
	}//更加简便
	return ret;
}
int main()
{
	char arr1[20] = "hello world";
	char arr2[] = "xxxxxxxx";
	//my_strcpy(arr1, arr2);
	my_strcpy(arr1 + 4, arr2);
	printf("%s\n", arr1);

	return 0;
}

1.3 strcat的使用和模拟实现

//1.3 strcat 追加、
//char * strcat(char* destination,const char* source)
//源字符串必须以'\0'结束
//目标空间(destination)必须足够大,以确保能存放源字符串
//目标空间必须可修改

//没涉及到返回值,就用void my_strcat(char* dest, const char* src)
//一旦涉及到返回值

//模拟实现strcat
char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(*dest != NULL);
	assert(*src != NULL);
	while (*dest)
	{
		dest++;
	}
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

int main()
{
	char arr1[20] = "hello";
	char arr2[] = "world";
	my_strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

1.4 strcmp的使用和模拟实现

//1.4 strcmp 字符串比较大小(比较对应位置的大小)
//int strcmp(const char * str1,const char * str2)
//vs环境下:str1>str2返回 1,str1=str2返回 0,str1<str2返回 -1
//

//strcmp例子
int main()
{
	int ret = strcmp("abc", "abcd");
	printf("%d\n", ret);
	return 0;
}

//模拟实现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);
	/*if (*str1 > *str2)
	{
		return 1;
	}
	else
	{
		return -1;
	}*/
}
int main()
{
	int ret = my_strcmp("abc", "abcd");
	printf("%d\n", ret);
	return 0;
}

1.5 strncpy,strncat,strncmp的使用实现

//1.5 strncpy(带n限定字符个数)
//char* strcpy(char * destination,char * source,size_t num)
//strncpy使用
int main()
{
	char arr1[20] = "abcdef";
	char arr2[] = "xx";
	strncpy(arr1, arr2,3);
	printf("%s\n", arr1);
	return 0;
}

//strncat使用
int main()
{
	char arr1[20] = "abcdef\0yyyyy";
	char arr2[] = "xxx";
	strncat(arr1, arr2, 5);
	printf("%s\n", arr1);
	return 0;
}

//strncmp使用
int main()
{
	char arr1[] = "abcd";
	char arr2[] = "abcf";
	printf("%d\n", strncmp(arr1, arr2, 3));
	return 0;
}

1.6 strstr的使用和模拟实现

//1.6 strstr 字符串中找子字符串
// 

int main()
{
	char arr1[] = "abcdefabcdef";
	char arr2[] = "deo";
	char* ret = strstr(arr1,arr2);
	if (ret != NULL)
		printf("%s\n", ret);
	else
		printf("找不到~");
	return 0;
}


//注意:可以了解KMP算法,找字符串的算法
char* my_strstr(char* str1, char* str2)
{
	assert(*str1);
	assert(*str2);
	if (*str2 == '\0')
	{
		return str1;
	}
	char* cp = str1;
	//      str1  
	//arr1 :a b b b c d e f \0
	//      cp
	//      s1
	char* s1 = cp;
	char* s2 = str2;
	//      str2
	//arr2 :b b c \0
	//      s2
	while (*cp)
	{
		s1 = cp;
		s2 = str2;
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return cp;
		}
		cp++;
	}
	return NULL;
}
int main()
{
	char arr1[] = "abbbcdef";
	char arr2[] = "bbc";
	char* ret = my_strstr(arr1, arr2);
	if (ret != NULL)
		printf("%s\n", ret);
	else
		printf("找不到~");
	return 0;
}

1.7 strtok的使用和模拟实现

//1.7 strtok
//char * strtok(char*str,const char*sep);
//sep参数是个字符串,定义了用作分隔符的字符合集
//strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针

int main()
{
	char arr[] = "bitllrrtt@yeah.net";
	char copy[20];
	strcpy(copy, arr);
	char sep[] = "@.";
	char* ret = NULL;
	for (ret = strtok(copy, sep); ret != NULL; ret = strtok(NULL, sep))
	{
		printf("%s\n",ret);
	}
	/*char* ret=strtok(copy, sep);
	printf("%s\n", ret);
	ret = strtok(NULL, sep);
	printf("%s\n", ret);
	ret = strtok(NULL, sep);
	printf("%s\n", ret);*/
	return 0;
}

1.8  strerror的使用和模拟实现

//1.8 strerror(报运行错误)
//char * strerror(int errnum);
//库函数在执行的时候,发生了错位,
//会将一个错误码存放errno这个变量中
//errno是c语言提供的一个全局变量

//列举前十行的错误
int main()
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d: %s\n", i,strerror(i));
	}
	return 0;
}

//打开文件示例strerror(实际打不开哈~)
int main()
{
	//c语言中操作文件
	//操作文件
	//1.打开文件
	//2.读/写
	//3.关闭文件
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		//printf("%s\n", strerror(errno));
		perror("fopen");
		return 1;
	}
	fclose(pf);
	return 0;
}

1.9 isupper,islower,toupper,tolower使用

int main()
{
	//printf("%d\n", isupper('A'));//判断是否为大写,是1,否0
	//printf("%d\n", isdigit('a'));//判断是否为小写,是1,否0
	//printf("%c\n", tolower('A'));//转小写
	//printf("%c\n", toupper('a'));//转大写
	//应用
	char arr[10];
	gets(arr);
	char* p = arr;
	while (*p)
	{
		if (isupper(*p))
		{
			*p = tolower(*p);
		}
		p++;
	}
	printf("%s\n", arr);
	return 0;
}

二、内存函数

内存函数 memcpy   memmove    memcmp

2.1 memcpy的使用和模拟实现

//memcpy
//拷贝字符串,拷贝整型数组,拷贝结构体数据
//这个函数在遇到'\0'的时候不会停下
// memcpy函数是用来处理,不重叠的内存拷贝的
// 如果source和destination有任何的重叠,复制的结果都是未定义的
//void * memcpy ( void * destination, const void * source, size_t num 
//size_t num是字节数

//使用
int main()
{
	float arr1[] = { 1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0 };
	float arr2[5] = { 0 };
	memcpy(arr2, arr1, 8);
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%f ", arr2[i]);
	}
	return 0;
}

模拟
//函数拷贝结束后,返回目标空间的起始地址
void* my_memcpy(void* dest,const void* src,size_t num)
{
	void* ret = dest;
	assert(dest && src);
	while (num--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8};
	int arr2[20] = { 0 };
	my_memcpy(arr2, arr1, 10);
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

2.2 memmove的使用和模拟实现

//memmove 
// 用它就完了
// 可重叠的内存拷贝
//void * memmove ( void * destination, const void * source, size_t num)

//使用
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10};
	//int arr2[20] = { 0 };
	memmove(arr1+2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

//模拟
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--)//20
		{
			*((char*)dest+num) = *((char*)src+num);
		}
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	//             1,2,1,2,3,4,5,8,9,10
	int arr2[] = { 1,2,3,4,5,6,7,8,9,10 };
	//             3,4,5,6,7,6,7,8,9,10
	my_memmove(arr1 + 2, arr1, 20);
	my_memmove(arr2, arr2 + 2, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	printf("\n");
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

 2.3 memcmp的使用

//memcmp 比较内存
//int memcmp(const void * ptr1, const void * ptr2,size_t num)
//

int main()
{
	char arr[] = "hello bit";
	memset(arr+1,'x',4);//以字节为单位设置的
	printf("%s\n", arr);
	return 0;
}

感谢您的阅读,如果对您有帮助,请留个赞赞哦~~

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值