字符串函数的使用与模拟

函数简介

字符函数是处理单个字符的函数集合,它们常用于分析字符的属性、转换字符格式或进行字符编码操作。例如,charCodeAt 可以返回字符串中特定位置的字符编码,而 fromCharCode 则执行相反的操作,将编码转换为字符。此外,toUpperCasetoLowerCase 分别将字符转换为大写或小写形式。这些函数为文本处理提供了基础工具,使得对字符级别的操作成为可能。本文章将会较为系统性介绍子字符串函数。

求字符串长度
 strlen
长度不受限制的字符串函数
 strcpy
 strcat
 strcmp
长度受限制的字符串函数介绍
 strncpy
 strncat
 strncmp
字符串查找
 strstr
 strtok
错误信息报告
 strerror
字符操作
内存操作函数

 memcpy
 memmove
 memset
 memcmp

函数介绍

strlen

函数介绍

strlen函数,其作用是获取字符串的长度,需要注意的是:

strlen是初始化的长度,并非存放字符串的空间长度。 

函数定义方式:

size_t strlen ( const char * str );

字符串的长度取决于strlen是否识别到null字符(也就是\0),stlren会返回在字符串中出现'\0'前面的字符个数,在使用这个函数时要注意这一点。

那我们来验证一下

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[] = { "abcdef" };
	char arr2[] = { 'a','b','c','d' };
	int ret1 = 0, ret2 = 0;
	ret1 = strlen(arr1);
	ret2 = strlen(arr2);
	printf("%d\n%d", ret1, ret2);
	return 0;
}

执行的结果如下: 

 我们可以看到,在地址中arr2字符数组的存储情况,可以知道,当strlen函数访问到 00 时,才停止访问,最后得到了33这个字符串长度。

其实,上面的代码存在一个小错误,不知道你们发现了没有呢?看看下面的代码会不会给你启发!

#include <stdio.h>
int main()
{
 const char*str1 = "abcdef";
 const char*str2 = "bbb";
 if(strlen(str2)-strlen(str1)>0)
 {
 printf("str2>str1\n");
 } 
 else
 {
 printf("srt1>str2\n");
 }
 return 0;
}

 请问这个代码最后会输出什么结果?是不是最终会出来负数?

  结果如下:

返回的结果str2>str1,为什么会出现这样的结果

size_a是strlen函数的返回值,size_a是无符号整形,所返回的整形是没有符号的,所以也无关乎是否存在小于0的情况了。

这也是为什么上面int类型的ret接受strlen的返回值会在编译器出现警告的原因、

模拟实现strlen

既然我们已经知道strlen的使用方式与功能,为了加深了解,我们自己来编写函数模拟实现strlen的功能:

模拟函数命名为my_strlen,首先我们应该对其进入函数的字符串进行判断,判断其是否合法,是否可以进入函数。

因为函数返回无符号整形,我们可以利用一个计数器count,当指针遍历整个字符串时,count自增,直到指针遇到'\0'时,count停止计数并返回其值,那么代码如下:

size_t my_strlen(const char* str)
{
	size_t count = 0;
	assert(str != NULL);
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}

assert函数调用判断需要使用<assert.h>这个库函数,const修饰变量,表示其变量只读,不会被修改,代码更具有健硕性

那么,如果不使用临时变量,是否也能实现strlen的功能呢?我们可以用递归来描述:

size_t my_strlen( const char* str)
{
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen(1 + str);
}

strcpy

函数介绍

在这里,我同样将cplusplus网站对于函数的解释奉上:

strcopy函数是将某字符串复制到指定的空间中(包括\0),其中返回类型为char*,两个参数类型为char* 的函数类型。

同样的,函数定义及使用方法:

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

其中strcopy函数需要指定的目标空间足够大,且空间必须可变以确保可以放置源字符串。

为什么需要空间可变呢?我们来看一下的代码用例:
 

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

int main()
{
	char* p = "asdfghjkl";//此代码在C++格式下,是错误的
	char arr[] = {" hello world "};
	strcpy(p, arr);
	printf("%s", p);
	return 0;
}

最后编译出现的情况是: 

指针p内指向的指向的是常量字符串,这是不允许修改的,所以此空间内无法复制数据进入!

模拟实现strcpy

如果我们要想实现此函数的功能,我们应该如何实现呢?

对于函数strcpy的功能我们已有所了解,那么通过对两者指向的地址空间进行操作,来完成''复制''这一操作

char* my_strcpy(char* dest, char* scre)
{
	while (*scre != '\0')
	{
		*dest = *scre;
		dest++;
		scre++;
	}
	*dest = *scre;
}

当然,这个设计还可以改进:

char* my_strcpy(char* dest, char* scre)
{
    char* ret=0;
    ret = dest;
	assert(dest != '\0');
	assert(scre != '\0');
	while (*dest++ = *scre++)
	{
		;
	}
	return ret;
}
NULL#define NULL  本质为0,指针的初始化
\0/ddd的转移字符 本质也是0
0数字0
NUL/nul\0
'0'字符0 本质48

strcat

函数介绍

在此,我同样贴上这个函数的介绍:

此函数使用时:

源字符串必须以 '\0' 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。
字符串自己给自己追加,可能会导致死循环。
那么,函数的定义与使用方式:
char * strcat ( char * destination, const char * source );

其函数的作用是将两个char类型连接,如下代码示例:

模拟实现strcat

为了实现库函数strcat作用,我们使用两个指针,一个寻找源空间中存放的'\0',另一指针在此基础上,将数据拷贝过来。代码示例如下:

char* my_strcat(char* dest, const char* scre)
{
	char* ret = 0;
	ret = dest;
	assert(dest && scre);
	//查询目标空间'\0'
	while (*dest)
	{
		dest++;
	}
	//拷贝数据
	while (*dest++ = *scre++)
	{
		;
	}
	return ret;
}

strcmp

函数介绍

strcmp是对于两个字符串中的字符进行对比,比较其大小,而不是比较字符串的长度。 

模拟实现strcmp

若要模拟实现其功能,通过传入的两个地址,对两个字符串进行比较,最后两个指针指向的字符,将其强制类型转换为整形,传回两个参数相减的值。

int my_strcmp(const char* s1, const char* s2)
{
	while (*s1 == *s2)
	{
		if (*s1 == '\0')
			return 0;
		s1++;
		s2++;
	}
	return *s1 - *s2;

strncpy strncat strncpy

上面介绍的函数,在使用时是长度不受限制的,寻找到NULL才停止,而strncpy strncat strncpy三个函数是长度受限制的字符串函数。

 strncmp介绍

 strncpy介绍 

 strncat介绍

 C语言推出的三个函数,在传入参数是多规定一个无符号整形,意在限制函数操作的字符串长度。

当需要操作的数大于被操作数,会以'\0'来作填补。

strstr

函数介绍

 strstr函数的作用是,两个字符串进行操作,返回字符串中在另外一个字符串首次出现的地址。

函数的使用方式如下:

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

函数模拟实现

想要模拟实现strstr的功能,需要考虑情况较多{"asdfg","aaasdfggg"},{"abbbcedf","bbc"}类似于这种字符串,只依靠两个指针无法完成此复杂功能,所以需要多个指针,代码如下:

char* my_strstr(const char* str1, const char*str2)
{
	const char* cur = str1;
	const char* s1 = NULL;
	const char* s2 = NULL;

	assert(str1 && str2);
	if (*str2 == '\0')
	{
		return (char*)str1;
	}

	while (*cur)
	{
		s1 = cur;
		s2 = str2;
		while (*s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return (char*)cur;
		}
		cur++;
	}
	return NULL;
}

在函数体内部在设置三个指针,一个指向被查找空间位置,另外两个分别指向两个传入的地址,与传入的指针一同进行操作。

  • 24
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夕·誓

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值