c语言(字符函数和字符串函数模拟实现)

strlen函数

size_t strlen ( const char * str );

strcpy函数

char* strcpy(char * destination, const char * source )

源字符串必须以'\0'结束,因为拷贝的时候遇到源字符的\0才会停止;会将源字符串中的'\0'拷贝到目标空间;目标空间必须足够大,以确保能存放字符串;destination的类型是char*,一般都是采用字符数组接收。

char* my_strcpy(char* des, const char* src)
{
	assert(des);
	assert(src);
	char* tmp = des;
	while (*des++ = *src++)//比较简洁高效
	{
		;
	}
	return tmp;
}

strcat函数

char * strcat ( char * destination, const char * source );

源空间和目标空间都必须要有\0,目标空间必须足够大,能容纳下源字符串的内容;目标空间必须可以修改;字符串自己给自己追加是会出错

char* my_strcat(char* des, const char* src)
{
	char* tmp = des;
	while (*des != '\0')
	{
		des++;
	}
	while (*des++ = *src++)
	{
		;
	}
	return tmp;
}

strcmp函数

int strcmp ( const char * str1, const char * str2 );

第一个字符串大于第二个字符串,返回大于0的数;等于返回0;小于返回小于0的数字

int my_strcmp(char* s1, char* s2)
{
	assert(s1 && s2);
	while (*s1 == *s2)
	{
		if (*s1 == '\0')
		{
			return 0;
		}
		s1++;
		s2++;
	}
	//if (*s1 > *s2)
	//{
	//	return 1;
	//}
	//else
	//	return -1;
	//上面注释掉的几行也没什么问题,但可以进行如下的优化
	return *s1 - *s2;//因为函数只要求大返回正数小返回负数就可以了,并不要求是±1
}

strncpy函数

char * strncpy ( char * destination, const char * source, size_t num );

拷贝num个字符从源字符空间到目标空间;如果源字符串的长度小于num,则拷贝完源字符串之后,在目标空间追加\ 0,直到num个

//
int main()
{
	char str[] = "This is a simple string";
	char* pch;
	pch = strstr(str, "simple");
	printf("%s\n", pch);//simple string
	strncpy(pch, "sample", 6);//sample string
	printf("%s", pch);
	return 0;
}

strncat函数

char * strncat ( char * destination, const char * source, size_t num );

向目标字符串追加源字符串的前num个字符

自己给自己追加采用strncpy是比较合适的 

int main()
{
	char arr1[20] = "abcd\0efghijk";
	char arr2[] = "abcdef";
	strncat(arr1, arr2, 2);//追加之后覆盖了之前的\0,但是末尾要添加新的\0
	return 0;
}

strstr函数

char * strstr ( const char *str1, const char * str2);

在str1中找str2是否存在,如果存在,返回一个指针,该指针指向str1中第一次出现str2的位置。如果不存在,返回NULL。

char* my_strstr(const char* s1, const char* s2)
{
	const char* str1;
	const char* str2;
	if(*s2 == '\0')
	{
		return s1;
	}
	while (*s1)//不要写成了while(s1),s1是指针,是一个地址
	{
		if (*s1 == *s2)
		{
			str1 = s1;
			str2 = s2;
			while (*str1 == *str2 && *str2)
			{
				str1++;
				str2++;
			}
			if (*str2 == '\0')
			{
				return s1;
			}
		}
		s1++;
	}
	return NULL;	
}

strtok函数

char * strtok ( char * str, const char * sep )

sep参数是个字符串,定义了用作分隔符的字符集合。

第一个参数指定一个字符串,它包含了0个或多个有sep字符串中一个或多个分隔符分割的标记。strtok函数会找到str的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针(这里我们也可以知道strtok是会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可以修改。)

意思就是char str[ ]="wjj@qq.com",const char* sep="@.";strtok (str, sep)之后会将@替换成'\0',并返回w的指针 。再一次调用strtok (NULL, sep),函数会从被替换成'\0'的@位置开始往下找下一个标记'.'并将其替换成'\0'然年后返回q的地址。

strtok函数的第一个参数为NULL,函数将在同一个字符案串中被保存的位置开始(该函数有记忆功能),查找下一个标记。

strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记,这是为什么第二次调用strtok的时候第一个参数要穿NULL的原因。

找不到下一个标记就返回NULL
 

int main()
{
	char str[] = "wjj@qq.com";
	const char* sep = "@.";
	char buffer[20] = { 0 };//拷贝,避免对源字符串进行改动
	strcpy(buffer, str);
	char* tmp = strtok(buffer, sep);
	printf("%s\n", tmp);
	tmp = strtok(NULL, sep);//第二次调用穿的一个参数是NULL
	printf("%s\n", tmp);
	tmp = strtok(NULL, sep);
	printf("%s\n", tmp);
	tmp = strtok(NULL, sep);//找不到下一个标记为,就返回NULL
	printf("%s\n", tmp);
	tmp = strtok(NULL, sep);
	printf("%s\n", tmp);
	return 0;
}

优雅一点的写法:

int main()
{
	char str[] = "wjj@qq.com";
	const char* sep = "@.";
	char buffer[20] = { 0 };//
	strcpy(buffer, str);
	char* tmp;
	for (tmp = strtok(str, sep); tmp != NULL; tmp = strtok(NULL, sep))
	{
		printf("%s\n", tmp);
	}
	return 0;
}

strerror函数

将错误码传换成错误信息,比如说浏览器的404就是错误码,这里的错误码是c语言中库函数报错的时候的错误码。

int main()
{
	printf("%s\n", strerror(0));
	printf("%s\n", strerror(1));
	printf("%s\n", strerror(2));
	printf("%s\n", strerror(3));
	printf("%s\n", strerror(4));
	printf("%s\n", strerror(5));
}

strerror的应用情况

int main()
{
	//错误码记录到错误码的变量中
	//errno - C语言提供的全局的错误变量,需要#include <errno.h>
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");//void perror(const charz*);传的参数可以自己定义,然后函数会在后面加':'再打印的也是errno变量中错误码对应的错误信息。perror=printf+strerror
		printf("%s\n", strerror(errno));//打印的errno变量中错误码对应的错误信息
		return 1;
	}
	//读文件
	fclose(pf);
	pf = NULL;
	return 0;
}

字符分类函数和字符转换函数

isdigit: 十进制数字 0~9

islower :小写字母a~z

isupper:大写字母A~Z

isalpha:字母a~z或A~Z

isalnum:字母或者数字,a~z,A~Z,0~9

int tolower ( int c );

int toupper ( int c );

memcpy函数 

void * memcpy ( void * destination, const void * source, size_t num );将源指针指向的num个字节的数据拷贝到目标指针所指向的地址上去。void* 可以接收任意类型的地址

//该函数不适用于重叠内存的拷贝
void* my_memcpy(void* dest, void* src, size_t num)
{
	void* tmp = dest;
	assert(dest);
	assert(src);

	while(num--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return tmp;
}

memmove函数

重叠内存的拷贝是交给memmove函数来实现的 

void* my_memmove(void* dest, void* src, size_t num)
{
	void* ret = dest;
	assert(dest);
	assert(src);
	if (dest < src)//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;
}

memcmp函数 

int memcmp ( const void * ptr1, const void * ptr2, size_t num );并不在乎比较的是声明类型的数据,都是void*。和strncmp非常的类型,只是参数有所差异,strncmp只能比较字符串,但是memcmp可以比较任何类型。

int main()
{
	int arr1[] = { 1,2,3,0,5 };//01 00 00 00 02 00 00 00 03 00 00 00 00 00 00 00 ..
	int arr2[] = { 1,2,3,4,0 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 ..
	int ret = memcmp(arr1, arr2, 13);
	printf("%d\n", ret);//-1
	return 0;
}

memset函数

void * memset ( void * ptr, int value, size_t num );以字节为单位进行设置

int main()
{
	int arr[] = { 1,2,3,4,5,6 };
	memset(arr, 1, 13);
	for (int i = 0; i < 6; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
综合小区管理系统管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、车位管理、车位分配管理、出入管理、字典管理、房屋管理、物业费缴纳管理、公告管理、物业人员投诉管理、我的私信管理、物业人员管理、用户管理、管理员管理。用户的功能包括管理部门以及部门岗位信息,管理招聘信息,培训信息,薪资信息等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 综合小区管理系统管理系统可以提高综合小区管理系统信息管理问题的解决效率,优化综合小区管理系统信息处理流程,保证综合小区管理系统信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理综合小区管理系统信息,包括出入管理,报修管理,报修管理,物业费缴纳等,可以管理操作员。 出入管理界面,管理员在出入管理界面中可以对界面中显示,可以对招聘信息的招聘状态进行查看,可以添加新的招聘信息等。报修管理界面,管理员在报修管理界面中查看奖罚种类信息,奖罚描述信息,新增奖惩信息等。车位管理界面,管理员在车位管理界面中新增。公告管理界面,管理员在公告管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值