字符串函数

在编写程序的过程中,我们经常需要用到字符串函数,为了方便对字符串进行处理,C语言标准库中提供了一系列库函数。在使用标准库中的字符串函数之前,我们需要引用头文件string.h。

接下来我们对经常用到的字符串函数进行逐一介绍。

strlen的使用和模拟实现

strlen的全称是string length,意思是求字符串的长度。

strlen的使用

strlen函数的参数和返回值的类型如下:

可以看到,我们需要传给strlen函数的参数是一个指针(字符串名代表字符串中首元素地址),返回的是字符串中'\0'之前字符的个数,且返回值的类型是size_t(size_t是一种无符号整型)。

例如:

输出结果为:

可以看到,strlen函数确实是返回了字符串中'\0'之前的字符个数。

从输出结果中,我们得出一下几点:

  • 传递给strlen函数作为参数的字符串中必须以'\0'结尾。
  • 给strlen函数的参数必须是一个字符指针。
  • stelen函数的使用必须包含头文件string.h。
  • strlen函数的返回值是一个无符号整型。

strlen的模拟实现

通过strlen函数的使用,我们知道了strlen函数的作用,为了加深对strlen函数的理解,接下来我们可以对strlen函数进行模拟实现。

例如:

为了和strlen函数进行区分,我们将自定义的函数命名为my_strlen,函数的返回类型为size_t,count用来计算字符个数,为了使count和函数的返回值类型一致,我们将count的类型也设置为size_t。

输出结果为:

输出结果与字符串中字符个数相匹配,完成模拟实现。

注:字符串中自动以‘\0’结尾,若输入strlen函数中的是字符数组,必须在结尾加上'\0',否则数组会越界,直到遇到‘\0’才停止。

strcpy的使用和模拟实现

strcpy的全称是string copy,意思是对字符串进行复制。

strcpy的使用

可以看到,strcpy函数的返回值是一个字符指针,指向的是复制好的字符串的首元素地址。strcpy函数的第一个参数是要复制数据进去的字符串的地址,第二个参数是被复制数据的字符串的地址。

例如:

输出结果为:

可以看到,str2字符串被复制到了str1字符串中。

从输出结果中,我们需要注意一下几点:

  • strcpy函数的返回值是一个指针,可以使用字符指针接受,也可以不接受。
  • str1的空间必须大于大于str2的空间,否则数组会越界。
  • 在使用strcpy函数之前必须引用头文件string.h。
  • str1的内容必须是可修改的。
  • 两个字符串都必须以'\0'结尾。

strcpy的模拟实现

从上面对strcpy函数的使用中,我们知道了strcpy函数的使用方法,为了加深对strcpy函数的理解,接下来我们对strcpy函数进行模拟实现。

例如:

为了与strcpy函数进行区分,我们将自定义函数命名为my_strcpy。通过循环将str2中的元素一个个复制给str1,直到遇到'\0',复制结束,最后将'\0'复制到str1中,返回str1首元素地址。

输出结果为:

可以看到,我们成功模拟实现了strcpy函数。

注意:参数1的空间一定要大于等于参数2的空间,否则会造成越界。

strcat的使用和模拟实现

strcat为Concatenate strings,意思是连接字符串

strcat的使用

可以看到,strcat函数的返回值是一个字符指针,指向连接好的字符串的首元素地址,参数1为目标字符串首元素地址,参数2为源字符串首元素地址。

例如:

输出结果为:

可以看到,str1确实发生了改变,返回的地址确实为str1首元素地址。

从输出结果中,我们需要注意以下几点:

  • 参数1的空间必须足够大,否则会造成数组越界。
  • 参数1和参数2必须都以'\0'结尾。
  • 在使用strcat函数之前要引用头文件string.h。
  • 目标空间必须是可修改的。

strcat的模拟实现

通过上面对strcat函数的使用,我们已经了解了strcat函数的具体用法,为了加深对strcat函数的理解,接下来我们对strcat函数进行模拟实现。

例如:

可以看到,在my_strcat中,我们先是将str1的指针移动到'\0',在将str2的数据有序复制给str1,直到遇到'\0',在这个过程中,我们必须保证str1的空间足够容纳str1和str2的数据。

输出结果为:

从输出结果可以看出,我们成功对strcat函数进行模拟实现。

注意:参数1空间必须足够容纳参数1和参数2的内容。

strcmp的使用和模拟实现

strcmp为string compare,意思是比较字符串的大小。

strcmp的使用

可以看到,函数的返回值类型是一个整型,如果参数1比参数2大,则返回大于0的数,如果参数1比参数2小,则返回小于0的数,如果参数1和参数2相等,则返回0。

对字符串进行比较的时候,我们比较的是字符串中对应位置的字符的ASCII码值,ASCII码值大的字符串就大,以此类推。

例如:

输出结果为:

可以看出,g的ASCII码比f的ASCII码大,返回大于0的数字。

从输出结果可以看出,我们需要注意以下几点:

  • 参数1和参数2必须是以'\0'结尾的字符串。
  • 在使用strcmp函数之前需要引用头文件string.h。
  • 字符串的大小与字符串中对应位置字符的ASCII码有关,与字符串长度无关。

strcmp的模拟实现

从上面strcmp函数的使用中,我们已经对strcmp函数有了初步的了解,为了加深对strcmp函数的理解,接下来我们将模拟实现strcmp函数。

例如:

可以看出,在my_strcmp函数中,若是两个字符串相等,则返回0,若是不相等,则返回对应位置字符的ASCII码值的差,同样满足strcmp函数的要求。

输出结果为:

从输出结果可以看出,我们完成了对strcmp函数的模拟实现。

注意:字符串大小与字符串中对应位置的字符ASCII码值有关,与字符串长度无关。

strncpy的使用

strncpy与strcpy的作用相同,都是复制字符串,唯一的区别的strncpy多了一个参数num,可以定义

复制数据的个数。

可以看到,strncpy函数多了一个size_t类型的参数,用来定义复制的数据大小,其他参数以及函数返回值类型与strcpy相同。

例如:

输出结果为:

字符串复制结束后s2并不会在s1后面自动加'\0',这点与strcpy略有差异。

从输出结果来看,我们需要注意以下几点:

  • 参数1和参数2必须都是以'\0'结尾的字符串。
  • 参数1的内存空间必须足够大。
  • 在使用strncpy函数之前需要先引用头文件string.h。

strncat的使用

strncat函数与ctrcat函数作用相同,都是字符串连接函数,唯一的区别是strncat函数多了一个参数num,可以指定连接的字符个数。

可以看到,相比于strcat函数,ctrncat函数中多了一个参数num,用来指定连接字符的个数。

例如:

输出结果为:

从输出结果来看,我们需要注意以下几点:

  • 传给函数的参数1和参数2必须是以'\0'结尾的字符串。
  • 在使用strncat函数之前需要引用头文件string.h。
  • 参数3必须为正数。
  • 参数1的内存空间必须足够大。

strncmp的使用

strncmp函数与strcmp函数作用相同,都是字符串比较函数,唯一的区别是strncmp函数多了一个参数num,用来指定字符串中比较的字符的个数。

可以看到,相比于strcmp函数,strncmp函数多了一个参数,用来指定比较大小的字符个数。

例如:

输出结果:

从输出结果来看,我们需要注意以下几点:

  • 参数1和参数2必须是以'\0'结尾的字符串。
  • 参数3必须为正数。
  • 在使用strncmp之前需要引用头文件string.h。

strstr的使用和模拟实现

在许多应用场景中,我们需要在一个字符串中寻找另一个字符串,即在主串中寻找子串。如果碰到这种场景,我们可以使用strstr函数。

strstr为Locate substring,意思是查找子字符串。

strstr的使用

我们可以看到,strstr函数需要包含两个参数,参数1是主串的地址,参数2是子串的地址,返回值为主串中与子串匹配的字符串的地址。

例如:

输出结果为:

从输出结果可以看出,我们需要注意以下几点:

  • strstr函数的两个参数必须是以'\0'结尾的字符串;
  • 在使用strstr函数之前需要先引用头文件string.h。
  • 返回的是主串中与子串相同的数据的地址,若找不到则返回空指针

strstr的模拟实现

通过上面对strstr函数的使用,我们对strstr函数有了初步的认识,为了加深对strstr函数的理解,接下来我们将模拟实现strstr函数。

例如:

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

char* my_strstr(const char* str1, const char* str2)
{
	const char* s1 = NULL;
	const char* s2 = NULL;
	const char* cur = str1;
	if (*str2 == '\0')
	{
		return (char*)str1;
	}
	while (*cur)
	{
		s1 = cur;
		s2 = str2;
		while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return (char*)cur;
		}
		cur++;
	}
	return NULL;
}


int main()
{
	char str1[] = "abcdefghh";
	char str2[] = "efg";
	char* s = my_strstr(str1, str2);
	printf("%s\n", s);
	return 0;
}

可以看到,在my_strstr函数中,const是对指针进行修饰,使其无法对指针指向的内容进行更改,使指针变得相对安全。在返回指针的时候,为了使其与函数的返回值类型相同,使用(char*)将其强制类型转换成char*类型的指针。

输出结果为:

注意:若主串中有两个相同的子串,strstr函数的返回值是指向主串中第一个与子串匹配的字符串的地址。

以上为常用的字符串函数,若想了解更多字符串函数,请到https://legacy.cplusplus.com/

  • 40
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值