前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >库函数之字符函数与字符串函数(下)

库函数之字符函数与字符串函数(下)

作者头像
初阶牛
发布2023-03-20 11:11:59
4170
发布2023-03-20 11:11:59
举报
文章被收录于专栏:C语言基础C语言基础
前言

目录

一、strncpy函数,strncat函数,strncmp函数

头文件:#include <string.h>

看过上一篇的小伙伴们都知道,对于下列函数应该都有所了解.

strcpy函数:.拷贝字符串函数 strcat函数:.追加字符函数 strcmp函数:.字符串拷贝函数

这些函数在使用时,都是遇到’\0’,才停止他们的拷贝,追加,比较等操作 如果我们想要只操作其中的部分,就可以增加一个参数来实现. 由于功能参数等与前面的函数相似,本篇不做重点讲解.

函数作用

strncpy函数

拷贝num个字符从源字符串到目标空间

strncat函数

追加num个源字符到目标空间

strncmp函数

比较两个字符串的前num个字符,返回值与strcmp一致.

函数参数模型

char * strncpy ( char * destination, const char * source, size_t num ); char * strncat ( char * destination, const char * source, size_t num ); int strncmp ( const char * str1, const char * str2, size_t num );

参数介绍

增加一个size_t 类型的参数num,用于限定原来的函数.

模拟实现strncpy

代码语言:javascript
复制
#include <stdio.h>
#include <assert.h>
char* my_strncpy(char* strDest, const char* strSource, size_t count)
{
	assert(strDest);
	assert(strSource);
	char* ret = strDest;
	while (count--)
	{
		*strDest++ = *strSource++;
	}
	return ret;
}
int main()
{
	char arr1[20] = "xxxxxxxxxxxxxx";
	char arr2[] = "Hello CSDN!";
	int sz2 = sizeof(arr2) / sizeof(arr2[0]);
	printf("%s", my_strncpy(arr1,arr2,5));
	return 0;
}

运行结果:

Helloxxxxxxxxx

注意:

1.strncpy只拷贝num个字符,并不会额外附加’\0’字符. 2.如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个. 这个在模拟的时候并没有添加上去.

模拟实现strncat函数

代码语言:javascript
复制
#include <stdio.h>
#include <assert.h>
char* my_strncat(char* destination, const char* source, size_t num)
{
	assert(destination);
	assert(source);
	char* ret = destination;
	while (*destination != '\0')
	{
		destination++;
	}
	while (num--)
	{
		*destination++ = *source++;
	}
	return ret;
}

int main()
{
	char arr1[20] = "Hello ";
	char arr2[] = "CSDN!";
	int sz2 = sizeof(arr2) / sizeof(arr2[0]);
	printf("%s", my_strncat(arr1, arr2, 3));
	return 0;
}

运行结果:

Hello CSD

模拟实现strncmp函数

代码语言:javascript
复制
#include <stdio.h>
#include <assert.h>
int my_strncmp(const char* str1, const char* str2, size_t num)
{
	while (num--)
	{
		if (*str1 > *str2)
		{
			return 1;
		}
		else if (*str1 < *str2)
		{
			return -1;
		}
		str1++;
		str2++;
	}
	return 0;
}
int main()
{
	char arr1[20] = "aabbccdd";
	char arr2[] = "aabbcdef";
	int sz2 = sizeof(arr2) / sizeof(arr2[0]);
	printf("%d", my_strncmp(arr1, arr2, 5));
	return 0;
}

运行结果:

0

解释: 因为前5个字符相同,num个字符比较结束,认为是相同字符串.

二、strstr函数

strstr函数

头文件:#include <string.h>

函数参数模型

在这里插入图片描述
在这里插入图片描述

函数作用:

用于查找主字符串中是否包含子字符串.包含返回第一次匹配成功的字符首地址.不包含则返回NULL.

函数的应用

力扣------找出字符串中第一个匹配的下标. 通过strstr函数找到第一个匹配的字符指针,

该指针-字符串首地址指针=该字符的下标.

代码语言:javascript
复制
int strStr(char * haystack, char * needle){
    char*ret=strstr(haystack,needle);
    if(ret-haystack<0)//小于0时,返回-1;
    {
        return -1;
    }
    return ret-haystack;
}

模拟实现

  1. 创建三个指针
  2. p1指向主字符串首地址,p2指向子字符串首地址.
  3. ret用于保存p1回退的位置.
  4. 当*p1==p2时,p1和p2继续向后比较,当p1!=*p2时,说明ret位置不对,则ret++
  5. p1退回到ret位置,p2回到初始位置,重新比较.
  6. 直到p2指向’\0’,则匹配成功,p1指向’\0’则匹配失败.

动图解析:

在这里插入图片描述
在这里插入图片描述

代码实现:

代码语言:javascript
复制
#include <stdio.h>
#include <assert.h>
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	if (*str2 == '\0')//如果子字符串是空字符串,直接返回主字符串
	{
		return str1;
	}
	const char *ret,*p1,*p2;
	ret = p1 = str1;
	p2 = str2;
	while (*p1&&*p2)//循环停止条件为主字符串或者子字符串有一个为空
	{
		if (*p1 == *p2)//相等则继续比较
		{
			p1++;
			p2++;
		}
		else//不相等则返回指定位置重新比较
		{
			p1 = ++ret;
			p2 = str2;
		}
	}
	if (*p2 == '\0')//如果子字符串比较结束,则匹配成功
	{
		return ret;
	}
	else//否则匹配失败
		return NULL;
}
int main()
{
	char str1[20] = "ABBCDABBACBBD";
	char str2[] = "ABBA";
	char* ret = my_strstr(str1, str2);
	if (ret == NULL)
	{
		printf("没有找到\n");
	}
	else printf("%s", ret);
}

ABBACBBD

三、strtok函数

strtok函数 头文件:#include <string.h>

函数参数模型

strtok函数

在这里插入图片描述
在这里插入图片描述

函数作用:

将字符串str根据delimiters 中的字符进行分割.

参数介绍:

参数

意义

str

需要被分隔的字符串(第一次传参的时候),传入NULL指针时,会从上一次修改的地址处

delimiters

定义了用作分隔符的字符集合

函数应用

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
int main()
{
	char str1[30] = "123.456.789_111,222@333";
	char str2[30];
	char a[] = "._,@";
	strcpy(str2, str1);//因为strtok函数会改变传过去的字符串的内容,所以我们是将备份传过去
	char* ret;
	//除了第一次调用时第一个参数为str2以外,后面的调用都是传入NULL,这样才会继续向后寻找标记分隔字符.
	for (ret = strtok(str2, a); ret != NULL; ret = strtok(NULL, a))
	{
		printf("%s\n", ret);
	}
	return 0;
}

运行结果:

123 456 789 111 222 333

strtok函数注意事项:

strtok函数并不是一次就将字符串中的所有分隔字符改为’\0’,而是调用它一次,修改一个. strtok函数第一次调用时,会找到str中的第一个分隔符标记,并将其用 \0 结尾,然后返回一个指向这个标记的指针。 strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。:

strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。 strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。

如果后面已经没有标记分隔,则返回 NULL 指针.

四、strerror函数

sterror函数

在这里插入图片描述
在这里插入图片描述

函数作用

库函数在使用错误时,会返回一串数字,这些数字就是错误码. strerror函数用于返回错误码对应的错误信息.

例如:

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
int main()
{
	printf("%s\n", strerror(0));
	printf("%s\n", strerror(1));
	printf("%s\n", strerror(2));
	printf("%s\n", strerror(3));
	printf("%s\n", strerror(4));
	printf("%s\n", strerror(5));

	return 0;
}

No error Operation not permitted No such file or directory No such process Interrupted function call Input/output error

但是strerror函数并不是这样使用的,因为我们也不知道错误码是什么,像上面这种是属于提前预判了的. 在库函数执行错误后,会将错误码存放在一个error的变量中.所以一般strerror函数是这样使用的.

函数应用

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main()
{
	//打开文件
	FILE* pf = fopen("CSDN.txt", "r");
	if (pf == NULL)
	{
		//printf("%s\n", strerror(errno));
		perror("fopen");
		return 1;
	}
	
	//关闭文件
	fclose(pf);
	pf = NULL;//避免空指针
	return 0;
}

perror函数等价于printf(“%s\n”, strerror(errno)); 即strerror函数是返回指向错误信息的字符串地址,而perror函数是将错误信息直接打印出来.

希望这篇文章能帮助大家对c语言中的库函数有关字符函数和字符串函数有更深层的理解. 今天就先到这里啦!!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-03-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 一、strncpy函数,strncat函数,strncmp函数
    • 函数作用
      • strncpy函数
      • strncat函数
      • strncmp函数
    • 函数参数模型
      • 参数介绍
        • 模拟实现strncpy
          • 模拟实现strncat函数
            • 模拟实现strncmp函数
            • 二、strstr函数
              • 函数参数模型
                • 函数作用:
                  • 函数的应用
                    • 模拟实现
                      • 动图解析:
                      • 三、strtok函数
                        • 函数参数模型
                          • 函数作用:
                            • 函数应用
                              • strtok函数注意事项:
                              • 四、strerror函数
                                • 函数作用
                                  • 函数应用
                                  领券
                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档