IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 字符函数剖析 -> 正文阅读

[C++知识库]字符函数剖析

众所周知,字符串在C语言中有很重要的地位。有时候我们经常会涉及一些和字符串相关的操作,如字符串的拼接,查找,复制,对比等等,对此官方提供了一系列的库函数来实现这些丰富的功能,下面我就给大家介绍几个C语言的常用的字符相关的函数,并提供部分函数的模拟实现。

一.strlen():

相信大家对于这个函数相对比较熟悉了,这里我就不具体展开介绍了,如果想要了解使用和模拟实现,可以参考:?C语言strlen()函数及其模拟实现_c language____coder的博客-CSDN博客_模拟strlen并调用

这一篇文章,这里我就讲一个关于strlen的一个小细节,我们先来看strlen的函数原型:

?size_t strlen( const char *string );

返回值的类型是size_t,是对unsigned int的typedef ,也就是说strlen的返回值是无符号整型!

#include<stdio.h>
#include<string.h>
int main()
{  
	char arr1[] = "abcdef";
	char arr2[] = "abc";
	if (strlen(arr1) - strlen(arr2) > 0)
	{
		printf(">\n");
	}
	else
	{
		printf("<\n");
	}
	return 0;
}

实际会打印的是">",因为strlen返回的是无符号数,所以strlen(arr1)-strlen(arr2)是一个相当大的无符号数,因此打印的是" >"。

二.strcpy():

有的时候,我们会遇到这样的一个如下的应用场景:

char arr1[20]={0};

char arr2[]="abcdef";

要求:把arr2的内容拷贝到arr1中去

你可能会想出第一个解决方案:arr1=arr2,能否行得通呢?我们去测试一下代码:

int main()
{   
	char arr1[20] = { 0 };
	char arr2[] = "abcdef";
	arr1 = arr2;
	return 0;
}

答案是否定的!因为这个代码连编译都过不去!

?

?数组名是常量,不可以对常量进行赋值操作!

为了解决这个问题,strcpy()库函数就起到作用了,我们先来看strcpy的函数原型

char *strcpy( char *strDestination, const char *strSource );

strcpy函数有两个参数,一个是dest--->拷贝字符串到哪里去

另一个是source---->拷贝的内容(为了保护数据,用了const限定符)

返回的是dest(待拷贝数组的首元素地址)

接下来,我们就通过一个案例来体会一下strcpy函数。

#include<stdio.h>
#include<string.h>
#include<assert.h>
//strcpy函数的使用
int main()
{
	char arr1[20] = { 0 };
	char arr2[] = "abcdef";
	strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

运行结果:

?可以看到arr1数组的内容确实被改变成abcdef,也就是说strcpy()确实完成了拷贝的任务!

这时候可能就会有同学好奇,strcpy()函数只拷贝有效的字符吗?字符串结尾的' \0'它会拷贝吗?

下面我们就来探究一下这个问题:

#include<stdio.h>
#include<string.h>
#include<assert.h>
//探究strcpy()是否拷贝'\0'
int main()
{
	char arr1[] = "xxxxxxxxxx";
	char arr2[] = "abcdef";
	strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

假设没有拷贝arr2末尾的‘\0’,那么printf的%s将会一直解析到arr1的末尾才会停止。

因此打印的结果将会是: abcdefxxxx

假设拷贝了arr2末尾的‘\0’,那么%s将会解析到拷贝的‘\0’处

因此打印的结果将会是:abcdef

究竟是哪一种情况呢?运行一下程序结果如下:

?运行结果是第二种!这就说明说strcpy在拷贝的时候连source末尾的'\0'也一并拷贝了过来!

了解了strcpy函数的使用,我们试着尝试模拟实现这个函数的功能!

#include<stdio.h>
#include<assert.h>
//strcpy的模拟实现
//既然是模拟实现,就尽量要和库函数相似
 char* my_strcpy(char* dest, const char* src)
{
	 char* ret = dest;
//因为下面有对dest和src的解引用操作,所以要防止对空指针解引用
	 assert(dest && src);
//后置++先使用再递增,这样就能完成对应位置有效字符的拷贝
//由于strcpy会将源字符串的'\0'拷贝,所以我们的strcpy也应该完成这一任务
//而当*src=='\0'时,while循环的表达式值为0,停止循环,同时也完成了'\0'的拷贝工作
	 while (*dest++ = *src++)
	 {
		 ;
	 }
	 return ret;
}
int main()
{
	char arr1[20] = { 0 };
	char arr2[] = "abcdef";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

运行结果如下:

?注意:1.strcpy()不会关心目标空间是否能够容纳待拷贝字符串内容,即使空间不够,它依然会强行进行越界拷贝,这时程序就会崩溃!

2.不能对一块不能修改内容的内存空间使用strcpy()函数,此时程序会崩溃!

3.源字符串必须以‘\0’结尾

三 .strcat()函数

有的情况下,我们需要对两个字符串进行拼接,但是在C语言中,并不支持两个字符串用‘+’号进行连接,为了实现字符串拼接功能,strcat()函数便应运而生了。

我们先来看strcat的函数原型:

char *strcat( char *strDestination, const char *strSource );

strDestination:目标空间

strSource:拼接的部分

返回目标空间的首地址

?接下来我们同样通过一个案例来看strcat函数的用法

//strcat的使用
int main()
{
	char arr1[20] = "abcd";
	char arr2[] = "efh";
	strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

运行结果如下:

?两个字符串确实完成了拼接,那么接下来我们不妨实现一个自己的strcat()函数

char* my_strcat(char* dest, const char* src)
{   //保存原来的起始位置
    char* ret = dest;
    assert(dest && src);
    while (*dest)
    {
        ++dest;
    }
    //开始拼接,相当于strcpy
    while (*dest++ = *src++)
    {
        ;
    }
    return ret;
}
int main()
{
    char arr1[20] = "abcd";
    char arr2[] = "efhi";
    my_strcat(arr1, arr2);
    printf("%s\n", arr1);
 	return 0;
}

?运行结果如下:

?注意:1.strcat()同样不会管目标空间的容量,一旦目标空间太小,那么同样会因为非法访问而导致程序崩溃!?

2.不能对不可改变的空间使用strcat(),同样会导致程序崩溃!

拓展:

从以上的讨论可以看出,strcpy()和strcat()都存在一定的安全性问题,所以C语言又提供了另外的

版本

strncpy(char *strDestination, const char *strSource,size_t count );

strncat(char *strDestination, const char *strSource,size_t count);

其中提供了count参数,其目的是指定拷贝多少字节的数据到目标空间里去,在一定程度上提高了程序的安全性。

三.strstr()函数

可能这个函数相对来说比较陌生,我们先来看它 的函数原型

char *strstr( const char *string, const char *strCharSet );

它的功能就是在string中找子串strCharSet

这里我们需要明确子串的概念:子串必须是连续的!看下面的例子

abcdef//

bcd---->是abcdef的子串

bce--->不是abcdef的子串,是abcdef的子序列

而strstr()函数的功能就是在目标串中寻找子串:

接下来我们就来用这个strstr()函数:

#include<stdio.h>
#include<string.h>
#include<assert.h>
//strstr函数的使用
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "bce";
//查询结果有这2种情况
//1.查到了返回子串首元素在查找序列里的位置
//2.如果找不到,就返回NULL
	char* ret=strstr(arr1, arr2);
	if (NULL == ret)
	{
		printf("找不到\n");
	}
	else
	{
		printf("%s\n", ret);
	}
	return 0;
}

接下来,我们就来模拟实现一下这个函数:

char* my_strstr(const char* str, const char* substr)
{   
	const char* s1 = str;
	const char* s2 = substr;
	const char* cur = s1;
	assert(str && substr);
	//如果substr是空串,直接返回str
	if (*substr == '\0')
	{
		return (char*)str;
	}
//匹配过程
	while (*cur)
	{   //记录匹配的位置
		s1 = cur;
		s2 = substr;
		//*s1和*s2一个其中为'\0'就不用再匹配了
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return (char*)cur;
		}
		cur++;
	}
	//到这里就是没有匹配的子串
	return NULL;
}
int main()
{
	char arr1[] = "abbcdef";
	char arr2[] = "bcd";
	char* ret=my_strstr(arr1, arr2);
	if (NULL == ret)
	{
		printf("找不到\n");
	}
	else
	{
		printf("%s\n", ret);
	}
	return 0;
}

运行结果如下:

?以上就是strcpy strcat以及strstr函数的使用及模拟实现,下一次我会给大家带来关于

memcpy、?memmove、memset等函数的介绍和模拟实现,希望能够和大家共同进步,在这里祝贺大家新年快乐!


?

?

?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-28 11:42:41  更:2022-01-28 11:43:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:50:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码