C-字符串函数合集模拟实现介绍注意事项

目录

一.strlen求字符串长度函数

二.strcpy字符串拷贝函数

三.strcat字符串追加函数

 四.strcmp字符串比较函数

五. strncpy字符串受限拷贝函数

 六.strncat字符串受限追加函数

 七.strncpy字符串受限拷贝函数

 八.strncmp字符串受限比较函数

九.strstr字符串查找函数

 十.strtok

十一.strerror错误报告函数

 十二.字符分类函数


本章重点:

重点介绍处理字符和字符串的库函数的使用和注意事项

求字符串长度

strlen

长度不受限制的字符串函数

strcpy strcat strcmp

长度受限制的字符串函数介绍

strncpy strncat strncmp

字符串查找

strstr strtok

错误信息报告

strerror

字符操作

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在 常量字符串 中或者 字符数组中。

字符串常量 适用于那些对它不做修改的字符串函数

 字符串常量:

字符数组:

以下所有函数都需要#include<string.h>头文件 

一.strlen求字符串长度函数

函数原型:

  • 字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含'\0' )。
  • 参数指向的字符串必须要以 '\0' 结束。
  • 注意函数的返回值为size_t,是无符号的( 易错 ),size_t是unsigned int类型
  • 返回长度

字符串函数中必须要有'\0'

模拟实现strlen:

//strlen模拟实现
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
    assert(str);//断言函数
    int count = 0;
    while (*str++ != '\0')//只要没有遇到\0就++
    {
        count++;
    }
    return count;
}

int main()
{
    char arr[] = "abcdef";

    int a = my_strlen(arr);
    printf("%d\n", a);

    return 0;
}

运行结果:

 

二.strcpy字符串拷贝函数

函数原型:

原字符串指:想要拷贝内容到其他空间的字符串

目标空间指:即将被拷贝内容的字符串

  •  将源指向的字符串复制到目标所指向的数组中,包括终止空字符(并在此时停止)
  • 源字符串必须以 '\0' 结束
  • 会将源字符串中的 '\0' 拷贝到目标空间(易忘)
  • 目标空间必须足够大,以确保能存放源字符串
  • 目标空间必须可变,(上述的字符串常量就是不可修改)
  • 返回目标空间起始地址

strcpy函数实现:

//strcpy模拟实现
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
	assert(dest);
	assert(src);
	char* ret = dest;
	while (*ret++ = *src++)
	{
		;
	}

	return dest;
}

int main()
{
	char arr1[20] = "abc";
	char arr2[] = "hello word";

	printf("%s\n", my_strcpy(arr1, arr2));

	return 0;
}

运行结果:

三.strcat字符串追加函数

函数原型:

  • 将源字符串追加到目标字符串。目标空间的\0字符,在目标中被源的第一个字符覆盖,向后面覆盖结束直到源字符串\0也拷贝进去,从而组成新的字符串。 
  •  源字符串和目标字符串必须有 '\0',源字符串中'\0'是什么时候结束,目标字符串中的'\0'是什么时候开始 。
  • 源字符串必须以 '\0' 结束。
  • 目标空间必须有足够的大,能容纳下源字符串的内容。
  • 目标空间必须可修改
  • 不适合给自己添加:
  •        返回目标空间起始地址

 strcat模拟实现:

//strcat模拟实现
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* src)
{
	//1.找目标空间中的\0
	char* cur = dest;
	while (*cur)
	{
		cur++;
	}
	//2.拷贝源头数据到\0之后的空间
	while (*cur++ = *src++)//\0拷贝到cur后为假结束
	{
		;
	}

	return dest;
}

int main()
{
	char arr1[20] = "hello \0xxxxxxxxx";
	char arr2[] = "world";

	printf("%s\n", my_strcat(arr1, arr2));

	return 0;
}

运行结果:

遇到\0停止打印 

 四.strcmp字符串比较函数

只比较大小不会改变值,两个指针的加上const提高函数健壮性

  • 由于字符类型对应的是ASII码值,比较的是每一个元素值的大小并不是长度
  • 一个一个元素的比较大小,只比较\0之前的
  • 两个字符串必须有\0,遇到\0结束

标准规定:

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

strcmp函数实现:

//strcmp模拟实现
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* s1, const char* s2)
{
	assert(s1 && s2);
	while (*s1 == *s2)//两个元素一样进来,不一样返回
	{
		if (*s1 == '\0')//如果都遇到\0证明两个大小一样放回0
		{
			return 0;
		}
		s1++;
		s2++;
	}
	return *s1 - *s2;
}

int main()
{
	char arr[] = "abcdef";
	char arr2[] = "abcdd";
	int ret = my_strcmp(arr, arr2);
		if (ret < 0)
		printf("arr1<arr2\n");
	else if(ret>0)
		printf("arr1>arr2\n");
	else
		printf("arr1==arr2\n");

	return 0;
}

运行结果:

上述讲的都是长度不受限的字符串函数,接下来讲受限的字符串函数

五. strncpy字符串受限拷贝函数

主要不同: 

num是以字节为单位,字符类型只占一个字节,所以输入几就拷贝几个字符过去(之后的受限函数同理)

  • 拷贝num个字符从源字符串到目标空间
  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个
  • 返回目标空间起始地址

 strncpy模拟实现:

//strncpy模拟实现
#include<stdio.h>
#include<assert.h>

char* my_strncpy(char* dest, const char* src, size_t num)
{
	assert(dest && src);
	char* ret = dest;

	while (num && (*dest++ = *src++)) // 拷贝字符串
	{
		num--;
	}
	if (num) // 当count大于src的长度时,将补充空字符
	{
		while (--num)
		{
			*dest++ = '\0';
		}
	}
	return ret;
}

int main()
{
	char arr1[] = "123456789";
	char arr2[] = "abde";
	printf("%s\n", my_strncpy(arr1, arr2, 2));
	return 0;
}

运行结果: 

 

 六.strncat字符串受限追加函数

  • 将源字符串的前 num 个字符追加到目标,外加一个\0
  • strncat适合给自己追加
  • 返回目标空间起始地址

 七.strncpy字符串受限拷贝函数

  • 拷贝num个字符从源字符串到目标空间。
  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个
  • 返回目标空间起始地址

 num比源字符串大(arr2)同理补\0

 八.strncmp字符串受限比较函数

函数原型:

  • 由于字符类型对应的是ASII码值,比较的是每一个元素值的大小并不是长度
  • 比较的是num个arr1和arr2个字符

标准规定:

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

九.strstr字符串查找函数

函数原型:

  • 在一个字符串中找另一个字符串是否存在,存在返回子串第一次出现的起始地址
  • 不存在返回NULL

 

实现代码思路分析: 

模拟实现:

//strstr模拟实现
#include<stdio.h>
#include<string.h>
char* my_strstr(const char* str1, const char* str2)
{
	const char* s1 = str1;
	const char* s2 = str2;
	const char* p = str1;
	while (*p != '\0')
	{
		//重新指向开始比较的地址
		s1 = p;
		s2 = str2;

		while(*s1 != '\0' && *s2 != '\0' && (*s1 == *s2))
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')//s2等于\0了说明已经比较完了
		{
			return (char*)p;//找到了
		}
		p++;
	}
	return NULL;
}

int main()
{
	char arr1[] = "abcdefabcdef";
	char arr2[] = "cde";
	char* pc = my_strstr(arr1, arr2);
	if (pc == NULL)
	{
		printf("不存在");
	}
	else
	{
		printf("%s",pc);
	}
	return 0;
}

实现结果:

 十.strtok

函数原型:

  • sep参数是个字符串,定义了用作分隔符的字符集合:
  • 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
  • strtok函数找到str中的下一个标记,并将其用 \0 结尾(分隔符改为\0),返回一个指向这个标记的指针(注: strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容 并且可修改。)
  •  strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串 中的位置。
  • strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标 记。
  • 如果字符串中不存在更多的标记,则返回 NULL 指针。

函数使用: 

  •  
  • 第一次之后就不能这样传了,只=只能传NULL,除非要换对象:
  • 但是这样写也太龊了,用一个巧妙的写法:

十一.strerror错误报告函数

函数原型:

 功能: 把错误码转换成错误信息

里面的0.1.2.3.4就是C语言中的错误码

返回的是打印字符串的起始地址

#include<errno.h>

errno用来记录错误码

发生错误就会把错误码自动记录在errno变量中

这里再给大家介绍一个函数:

 需要包含头文件:#include<stdio.h>

不放自定义信息的时候:

 

 这样才符合语法

就相当于perror = printf + strerror 

但是他依然是从errno中拿错误码打印

好处是可以加自定义的信息

使用

在只想打印错误信息的时候用:perror

在想要拿到错误码的时候用:strerror

 十二.字符分类函数

都需要引头文件:#include<stype.h>

函数如果他的参数符合下列条件就返回真
iscntrl任何控制字符
isspace空白字符:空格‘ ’,换页‘\f’,换行'\n',回车‘\r’,制表符'\t'或者垂直制表符'\v'
isdigit十进制数字 0~9
isxdigit十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
islower小写字母a~z
isupper大写字母A~Z
isalpha字母a~z或A~Z
isalnum字母或者数字,a~z,A~Z,0~9
ispunct标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph任何图形字符
isprint任何可打印字符,包括图形字符和空白字符

用一个函数举例使用:

 字符转换函数:

int tolower ( int c );       //转小写
int toupper ( int c );      //转大写

 

tolower 若是小写不变

toupper 若是大写不变

制作不易,你们的回馈是作者最大的动力!!!

  • 20
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值