字符函数和字符串及其模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<assert.h>

//字符函数
//int main()
//{
//	int ret = islower('a');//如果是小写字母返回非零的值,其他返回0
//	printf("%d\n", ret);
//	return 0;
//}

//写一个代码,将字符串中的小写字母转大写,其他字符不变 'a'->97   'A'->65
//int main()
//{
//	char str[] = "i am A Student";//1.遍历字符串2.发现小写字母转大写
//	size_t len = strlen(str);
//	size_t i = 0;
//	for (i = 0; i < len; i++)
//	{
//		if (islower(str[i]))
//		{
//			//str[i] = str[i] - 32;
//			str[i] = toupper(str[i]);
//		}
//	}
//	printf("%s\n", str);
//	return 0;
//}
//也可以使用函数toupper
//int main()
//{
//	int ch = 0;
//	scanf("%c", &ch);
//	//ch = ch + 32;//大写转小写
//	ch = tolower(ch);//与上一行效果相等
//	printf("%c\n", ch);
//	return 0;
//}

//下面是字符串函数
//1.strlen:求字符串长度函数
// 
//下边三个函数不受长度限制,有可能产生安全问题。
//2.strcpy:字符串拷贝函数
//3.strcat函数:字符串追加
//4.strcmp函数:比较两个字符串大小
// 
//下边三个是长度受限制的函数
//5.strncpy 6.strncat 7.strncmp
// 
//8.strtok函数:按指定分隔符分割字符
//9.strstr函数:在字符串中查找另一个字符串,返回str2在str1中第一次出现的位置,如果没有出现,返回空指针
//10.strerror函数:返回一个错误码所对应的错误信息字符串的起始地址      const char * strerror(int i)

//strlen函数
//int main()
//{
//	char arr[] = "abcdef";
//	//a b c d e f \0
//	size_t len = strlen(arr);
//	printf("%zd\n", len);
//	return 0;
//	//1.strlen函数要正确获得字符串长度的话,字符串中必须要有\0
//}
//2.strlen函数的返回值是size_t,也就是无符号整型
//int main()
//{
//	if (strlen("sbc") - strlen("ancdef") > 0)//两个无符号数相减结果为无符号数  -3会变为一个及其大的数,可以前边加上(int)进行强制类型转换
//		printf(">\n");
//	else
//		printf("<=\n");
//	//结果为>
//	return 0;
//}

//strlen函数的模拟实现
//仿照strlen函数的参数,返回类型,功能写一个类似的函数
第一种实现方式:计数器方式
//size_t my_strlen1(const char * str)
//{
//	int count = 0;
//	assert(str != NULL);
//	while(*str != '\0')
//	{
//		count++;
//		str++;
//	}
//	return count;
//}
第二种实现方式:指针-指针--->地址-地址
得到的是指针和指针之间元素的个数
//size_t my_strlen2(const char*str)
//{
//	const char* start = str;
//	while (*str != '\0')
//	{
//		str++;
//	}
//	return str - start;
//}
第三种方法:不能使用临时变量(递归)
//size_t my_strlen3(const char*str)
//{
//	if (*str != '\0')
//		return 1 + my_strlen3(str + 1);
//	else
//		return 0;
//}
//int main()
//{
//	char arr[] = "abcdef";
//	size_t len = my_strlen1(arr);
//	size_t len = my_strlen2(arr);
//	size_t len = my_strlen3(arr);
//	printf("%zd\n", len);
//	return 0;
//}

//strcpy函数
//1.源字符串必须包含'\0',会将源字符串中的 '\0' 拷⻉到⽬标空间。拷贝到'\0'处停止拷贝
//2.要保证目标空间要足够大,能放得下拷贝来的数据
//3.保证目标空间必须可以修改(常量字符串不可被修改)
//int main()
//{
//	char arr1[] = "abcdef";
//	char arr2[20] = "xxxxxxxx";//不给出数组长度时根据数组元素个数定义长度
//	strcpy(arr2, arr1);//将字符串arr1拷贝到arr2中
//	printf("%s\n", arr2);
//	return 0;
//}

//模拟实现strcpy函数
//版本1
//void my_strcpy(char* dest, char* src)
//{
//	while (*src != '\0')//拷贝\0之前的字符
//	{
//		*dest = *src;
//		dest++;
//		src++;
//	}
//	//拷贝\0
//	*dest = *src;
//}
//版本2
//void my_strcpy(char* dest, char* src)
//{
//	while (*dest++ = *src++)
//	{
//		;
//	}
//}
//版本3
//void my_strcpy(char* dest, char* src)
//{
//    assert(dest);
//    assert(src);
//	  while (*dest++ = *src++)
//	  {
//		  ;
//	   }
//}
//版本4
//dest指向的空间是需要改变的,但是src指向的空间是不期望被改变的
//void my_strcpy(char* dest, const char* src)
//{
//	assert(dest && src);
//	while (*dest++ = *src++)
//	{
//		;
//	}
//}
//版本5
//返回目标空间的起始地址
//char* my_strcpy(char* dest, const char* src)
//{
//	char* ret = dest;
//	assert(dest && src);
//	while (*dest++ = *src++)
//	{
//		;
//	}
//	return ret;
//}
//int main()
//{
//	char arr1[] = "abcdef";
//	char arr2[20] = { 0 };
//	my_strcpy(arr2, arr1);
//	printf("%s\n", arr2);
//	printf("%s\n", my_strcpy(arr2, arr1));//只有版本5能这么用
//	return 0;
//}


//strcat函数:字符串追加
//1.目标空间中要有'\0'(从哪里开始追加),源头字符串中得有'\0'(追加到什么时候结束)
//2.目标空间要足够大,目标要可以修改
//int main()
//{
//	char arr1[20] = "hello ";
//	char* p = "world";
//	strcat(arr1, p);
//	printf("%s\n", arr1);
//	return 0;
//}

//模拟实现strcat
//char *my_strcat(char *dest,const char*src)//返回目标空间的起始地址
//{
//	char* ret = dest;
//	assert(dest && src);
//	//1.找到目标空间中的\0
//	while (*dest != '\0')
//	{
//		dest++;
//	}
//	//2.拷贝数据
//	while (*dest++ = *src++)
//	{
//		;
//	}
//	return ret;
//}
//int main()
//{
//	char arr1[20] = "hello ";
//	char* p = "world";
//	my_strcat(arr1, p);
//	printf("%s\n", arr1);
//	printf("%s\n", my_strcat(arr1, p));
//	printf("%s\n", my_strcat(arr1, arr1));//这样不行,dest指向的\0被修改成a,...,src永远不会指向\0,程序不会停止,会陷入死循环。
//	//想实现字符串自己追加自己可以使用strncat函数
//	return 0;
//}

//strcmp函数:用来比较两个字符串大小(按字典序比较)(按位依次比较)
//前<后,返回小于零的数
//前>后,返回大于零的数
//前==后,返回0
//int main()
//{
//	int ret = strcmp("abcdef", "abq");
//	printf("%d\n", ret);//返回-1
//	return 0;
//}

//模拟实现strcpy函数
//int my_strcmp(const char* s1, const char* s2)
//{
//	assert(s1 != NULL);
//	assert(s2 != NULL);
//	while (*s1 == *s2)
//	{
//		if (*s1 == '\0')
//		{
//			return 0;
//		}
//		s1++;
//		s2++;
//	}
//	//1.if (*s1 > *s2)
//	//	  return 1;
//	//  else
//	//	  return -1;
//	//2.return *s1 - *s2;
//}
//int main()
//{
//	int ret = my_strcmp("abcdef", "abc");
//	printf("%d\n", ret);
//	return 0;
//}

//strncpy函数   strncat函数和strncmp函数同理
//int main()
//{
//	char arr1[10] = "xxxxxxxx";
//	char arr2[] = "ab";
//	strncpy(arr1, arr2, 5);
//	printf("%s\n", arr1);
//	return 0;
//}

//strtok函数:返回类型为char*   char * strtok(char *str,const char * sep)
//strtok函数找到str中的下⼀个标记,并将其⽤ \0 结尾,返回⼀个指向这个标记的指针。
//注意:strtok函数会改变被操作的字符串,所以在使⽤strtok函数切分的字符串⼀般都是临时拷⻉的内容并且可修改。
//strtok函数的第⼀个参数不为 NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串中的位置。
//strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标记。
//如果字符串中不存在更多的标记,则返回 NULL 指针。
//int main()
//{
//	char arr[] = "zpengwei@yeah.net";//@ 和.称为分隔符
//	char buf[30] = { 0 };
//	strcpy(buf, arr);
//	char* p = "@.";
//	char * s = strtok(buf, p);
//	printf("%s\n", s);//打印出来的是zpengwei
//
//	s = strtok(NULL, p);
//	printf("%s\n", s);//yeah
//
//	s = strtok(NULL, p);
//	printf("%s\n", s);//net
//
//	return 0;
//
// }
//以上只是举例子,下面是正常写法
//int main()
//{
//	char arr[] = "zpengwei@yeah.net@xxxx.yyyy.zzzz";
//	char buf[60] = { 0 };
//	strcpy(buf, arr);
//	char* p = "@.";
//	char* r = NULL;
//	for (r = strtok(buf, p); r != NULL; r = strtok(NULL, p))
//	{
//		printf("%s\n", r);
//	}
//	return 0;
//}

//strstr函数:在字符串中查找另一个字符串,返回str2在str1中第一次出现的位置,如果没有出现,返回空指针
//int main()
//{
//	char arr1[] = "abcdefabcdef";
//	char arr2[] = "def";
//	char * ret = strstr(arr1, arr2);
//	if (ret != NULL)
//	{
//		printf("%s\n", ret);//打印出defabcdef
//	}
//	else
//		printf("找不到\n");
//	return 0;
//}

//模拟实现strstr函数
//const char* my_strstr(const char* str1, const char* str2)
//{
//	assert(str1);
//	assert(str2);
//	const char* cp = str1;
//	const char* s1 = str1;
//	const char* s2 = str2;
//	if (*str2 == '\0')//如果子串是空字符串,直接返回str1
//		return str1;
//	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[] = "abcdefabcdef";
//	char arr2[] = "def";
//	char * ret = my_strstr(arr1, arr2);
//	if (ret != NULL)
//	{
//		printf("%s\n", ret);//打印出defabcdef
//	}
//	else
//		printf("找不到\n");
//	return 0;
//}

//strerror函数:返回一个错误码所对应的错误信息字符串的起始地址      const char * strerror(int i)
//int main()
//{
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		char* ret = strerror(i);
//		printf("%d,%s\n", i, ret);
//	}
//	return 0;
//}
//当库函数调用失败时,会将错误码记录到errno这个变量中
//errno是一个c语言的全局变量

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值