一文带你玩转C库中的一系列字符串函数

这篇具有很好参考价值的文章主要介绍了一文带你玩转C库中的一系列字符串函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

作者主页:paper jie的博客_CSDN博客-C语言,算法详解领域博主

本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。

本文录入于《系统解析C语言》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将算法基础知识一网打尽,希望可以帮到读者们哦。

其他专栏:《算法详解》《C语言》《C语言-语法篇》等

内容分享:本期将对c语言中的一系列字符串函数进行详细的讲解,各位看官姥爷快搬好小板凳坐好叭。

    -------- 不要998,不要98,只要一键三连,三连买不了吃亏,买不了上当

目录

前言

求字符串长度

strlen的介绍与使用

strlen的模拟实现

方法一 计数器

递归二 递归

方法三 指针 - 指针

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

strcpy的介绍和使用

strcpy的模拟实现

strcat的介绍和使用

strcat的模拟实现

strcmp的介绍和使用

strcmp的模拟实现

长度受限制的字符串函数

strncpy的介绍和使用

strncpy的模拟实现

strncat的介绍和使用

strncat的模拟实现

strncmp的介绍和使用

strncmp的模拟实现 

字符串查找函数

strstr的介绍和使用

strstr的模拟实现

strtok的介绍

strtok的使用

错误信息报告

strerror的介绍和使用

字符分类函数

字符转换函数

转换函数的使用


前言

在大家使用C语言进行编程的时候,我们可以发现C中对字符和字符串的处理十分的频繁,但是呢,c它本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。字符串常量只使用于那些对它不做修改的字符串函数,字符数组可适用于任何字符串函数。今天,我们就要对这些函数一探究竟。

求字符串长度

strlen的介绍与使用

size_t strlen ( const char * str )
//strlen的使用

#include <stdio.h>
#include <string.h>
int main()
{
	char arr[] = "abcdef";
	size_t ret = strlen(arr);
	printf("%zu\n", ret);
	return 0;
}

字符串的'\0'作为结束标志,strlen返回的是'\0'前面出现的字符个数,'\0'不计入其中。

参数指向的字符串必须要以'\0'为结束。

strlen的返回值的类型为size_t,是无符号的。

这里解释一下第三个说明,举个栗子:通过下面代码我们可以发现arr1的长度明显大于arr2的长度,但是结果却是>。这就是因为strlen的返回类型是无符号的,两个无符号的相减,得到的还是无符号的。

int main()
{
	char arr1[] = "xxxxxxx";
	char arr2[] = "xxxx";
	if (strlen(arr2) - strlen(arr1) > 0)
		printf(">");
	else
		printf("<");
	return 0;
}

一文带你玩转C库中的一系列字符串函数,# 系统解析C语言,C语言,c语言,数据结构

strlen的模拟实现

方法一 计数器

int my_strlen(char* str)
{
	int count = 0;
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}

int main()
{
	char arr[] = "abcdef";
	int ret = my_strlen(arr);
	printf("%d\n", ret);
	return 0;
}

递归二 递归

int my_strlen(char* str)
{
	if (*str == 0)
		return 0;
	else
		return 1 + my_strlen(str + 1);
}

int main()
{
	char arr[] = "abcdef";
	int ret = my_strlen(arr);
	printf("%d\n", ret);
	return 0;
}

方法三 指针 - 指针

int my_strlen(char* str)
{
	char* p = str;
	while (*str != '\0')
	{
		str++;
	}
	return str - p;
}

int main()
{
	char arr[] = "abcdef";
	int ret = my_strlen(arr);
	printf("%d\n", ret);
	return 0;
}

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

strcpy的介绍和使用

char * strcpy ( char * destination, const char * source )
//使用strcpy函数
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "XXX";
	strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

源字符串必须以'\0'结束

会将字符串中的'\0'拷贝到目标空间

目标空间必须可变

这里解释一下第三个说明:strcpy的第一个参数只能是可变参数,也就是字符数组。不能是常量字符串,因为它不能改变。

strcpy的模拟实现

//模拟实现strcpy函数
//优化前
char* my_strcpy(char* dest, char* source)
{
	char* ret = dest;
	while (*source != '\0')
	{
		*dest = *source;
		dest++;
		source++;
	}
	*dest = '\0';
	return ret;	
}

//优化后
char* my_strcpy(char* dest, const char* source)
{
	char* ret = dest;
	assert(dest && source);
	while (*dest++ = *source++);
	return ret;
}

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "XXX";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

strcat的介绍和使用

char * strcat ( char * destination, const char * source )
//使用strcat函数
int main()
{
	char arr1[20] = "abcdef";
	char arr2[] = "xxxxx";
	strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

源字符串必须以'\0'结束

目标空间必须有足够的大,可以容纳下源字符串的内容

目标空间必须可以修改

这里解释一下第二个说明:因为要将源字符串放到目标字符串后面,所以他的空间大小必须大于等于两个字符串的大小,不然会溢出。

strcat的模拟实现

//模拟实现strcat
char* my_strcat(char* str1, const char* str2)
{
	assert(str1 && str2);
	char* ret = str1;
	while (*str1)
	{
		str1++;
	}
	while (*str1++ = *str2++);
	return ret;
}
int main()
{
	char arr1[20] = "abcdef";
	char arr2[] = "XXXX";
	my_strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

strcmp的介绍和使用

int strcmp ( const char * str1, const char * str2 );
//使用strcmp函数
int main()
{
	char arr1[] = "adcdef";
	char arr2[] = "adsdf";
	int ret =strcmp(arr1, arr2);
	printf("%d\n", ret);
	return 0;
}

第一个字符串大于第二个字符串,返回大于0的数字

第一个字符串等于第二个字符串,返回0

第一个字符串小于第二个字符串,返回小于0的数字

它们比较的是对应字符的ASCII码值,要是相等就比较下一个

strcmp的模拟实现

//模拟实现strcmp函数
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		else
		{
			str1++;
			str2++;
		}
	}
	if (*str1 > *str2)
		return 1;
	else if (*str1 < *str2)
		return -1;
}
int main()
{
	char	arr1[] = "adcdef";
	char arr2[] = "abcdef";
	int ret = my_strcmp(arr1, arr2);
	printf("%d\n", ret);
	return 0;
}

长度受限制的字符串函数

strncpy的介绍和使用

char * strncpy ( char * destination, const char * source, size_t num )
//使用strncpy函数
int main()
{
	char arr1[] = "adcdefdsaf";
	char arr2[] = "XXXxx";
	strncpy(arr1, arr2, 3);
	printf("%s\n", arr1);
	return 0;
}

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

如果源字符串的长度小于num,拷贝完源字符串后,在目标后面追加0,直到num个。

strncpy的模拟实现

//模拟strncpy
char* my_strncpy(char* dest, const char* str, int num)
{
 assert(dest && str);
	char* ret = dest;
	int i = 0;
	for (i = 1; i <= num; i++)
	{
		if (strlen(ret) < i)
		{
			*dest = '\0';
		}
		*dest = *str;
		dest++;
		str++;
	}
	return ret;
}
int main()
{
	char arr1[] = "adcdefdsaf";
	char arr2[] = "XXXxx";
	my_strncpy(arr1, arr2, 8);
	printf("%s\n", arr1);
	return 0;
}

strncat的介绍和使用

char * strncat ( char * destination, const char * source, size_t num )
//使用strncat函数 
int main()
{
	char arr1[20] = "adcdefdsaf";
	char arr2[] = "XXXxxxx";
	strncat(arr1, arr2, 5);
	printf("%s\n", arr1);
	return 0;
}

源字符串 的第一个数字字符追加到目标,外加一个终止空字符。

如果源字符串中 C 字符串的长度小于 num,则仅复制终止空字符之前的内容。

strncat的模拟实现

//模拟strncat函数
char* my_strncat(char* dest, const char* str, int num)
{
	char* ret = dest;
	assert(dest && str);
	while (*dest != '\0')
	{
		dest++;
	}
	int count = 0;
	int count = 0;
	while (count++, count<=num && count<=strlen(str))
	{
			*dest = *str;
			dest++;
			str++;
	}
	*dest = '\0';
	return ret;
}
int main()
{
	char arr1[20] = "adcdefd";
	char arr2[] = "XXXxxxx";
	my_strncat(arr1, arr2, 19);
	printf("%s\n", arr1);
	return 0;
}

strncmp的介绍和使用

int strncmp ( const char * str1, const char * str2, size_t num )
//使用strncmp函数
int main()
{
	char arr1[] = "abcdefg";
	char arr2[] = "abces";
	int ret = strncmp(arr1, arr2, 4);
	printf("%d\n", ret);
	return 0;
}

比较出现字符不一样或者一个字符串结束或者num个字符全部比较完

一文带你玩转C库中的一系列字符串函数,# 系统解析C语言,C语言,c语言,数据结构

strncmp的模拟实现 

//模拟strncmp函数
int my_strncmp(char* str1, char* str2, int num)
{
	int i = 0;
	for (i = 1; i <= num; i++)
	{
		if (*str1 == *str2)
		{
			if (*str1 == '\0')
				return 0;
			str1++;
			str2++;
		}
		else if (*str1 > *str2)
			return 1;
		else if (*str1 < *str2)
			return -1;
	}
}
int main()
{
	char arr1[] = "aefg";
	char arr2[] = "abces";
	int ret = my_strncmp(arr1, arr2, 4);
	printf("%d\n", ret);
	return 0;
}

字符串查找函数

strstr的介绍和使用

char * strstr ( const char * str1, const char * str2 )
//使用strstr函数
int main()
{
	char arr1[] = "abbbcd";
	char arr2[] = "bbc";
	char* p = strstr(arr1, arr2);
	puts(p);
	return 0;
}

作用是返回指向 str2 中第一次出现的 str1 的指针,如果 str2 不是 str1 的一部分,则返回一个空指针。匹配过程不包括终止空字符,但它到此为止。

返回值是指向 str1 中指定的整个字符序列在 str2 中首次出现的指针,如果序列在 str1 中不存在,则为 null 指针。

strstr的模拟实现

//模拟实现strstr函数
char* my_strstr(char* dest, const char* source)
{
	assert(dest && source);
	char* cp = dest;
	char* s1 = dest;
	char* s2 = source;
	if (*source == '\0')
		return dest;
	while (*cp != '\0')
	{
		while (*s1 == *s2&& *s1 && *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return cp;
		else
		{
			cp++;
			s1 = cp;
			s2 = source;
		}
	}
	return NULL;
}
int main()
{
	char arr1[] = "abbbbcd";
	char arr2[] = "bbc";
	my_strstr(arr1, arr2);
	printf("%s\n", my_strstr(arr1, arr2));
	return 0;
}

strtok的介绍

char * strtok ( char * str, const char * delimiters )

delimiters参数是一个字符串,定义了用做分隔符的集合

第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分割符

strtok函数找到str中的下一个标记,并将其用'\0'结尾,返回一个指向这个标记的指针注: strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容 并且可修改。)

strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标 记。
如果字符串中不存在更多的标记,则返回 NULL 指针。

strtok的使用

//使用strtok函数
int main()
{
	char arr[] = "3435151626@qq.com";
	char cpy[20];
	strcpy(cpy, arr);
	char* ret = NULL;
	char sep[] = "@.";
	for (ret = strtok(cpy, sep); ret != NULL; ret = strtok(NULL, sep))
	{
		printf("%s\n", ret);
	}

	return 0;
}

错误信息报告

strerror的介绍和使用

char * strerror ( int errnum );
//使用strerror函数
int main()
{
	int i = 0;
	for (i = 0; i < 9; i++)
	{
		printf("%d: %s\n", i, strerror(i));
	}
	return 0;
}

一文带你玩转C库中的一系列字符串函数,# 系统解析C语言,C语言,c语言,数据结构 返回错误码,做对应的错误信息

字符分类函数

函数 
如果他的参数符合下列条件就返回真
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将小写转大写文章来源地址https://www.toymoban.com/news/detail-548544.html

转换函数的使用

int main()
{
    char ch[10] = { 0 };
	gets(ch);
	char* p = ch;
	while (*p)
	{
		if (isupper(*p))
		{
			*p = tolower(*p);
		}
		p++;
	}
	printf("%s\n", ch);
	return 0;
}

到了这里,关于一文带你玩转C库中的一系列字符串函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 带你玩转双链表

    相信经过前面的学习,大家已经了解的单链表的缺陷和用途,今天我们学习双链表,和以前不同,今天双链表的实现我们增加一点点的难度,但我相信这些难度对大家都没有问题。和之前单链表的实现,我们的数据类型是固定的,主函数中传什么我们的单链表结构体中就需要

    2024年02月13日
    浏览(37)
  • 带你玩转modbusTCP通信

    Modbus TCP是一种基于TCP/IP协议的Modbus通信协议,它是Modbus协议的一种变体,用于在以太网上进行通信。Modbus TCP协议是一种开放的通信协议,它支持多种编程语言和操作系统,并且可以在不同的硬件和软件平台上进行通信。 Modbus TCP协议使用标准的TCP/IP协议栈,通过以太网进行通

    2024年02月03日
    浏览(47)
  • 【Apache-Flink零基础入门】「入门到精通系列」手把手+零基础带你玩转大数据流式处理引擎Flink(基础概念解析+有状态的流式处理)

    Apache Flink 是业界公认的最佳流计算引擎之一,它不仅仅局限于流处理,而是一套兼具流、批、机器学习等多种计算功能的大数据引擎。Flink 的用户只需根据业务逻辑开发一套代码,就能够处理全量数据、增量数据和实时数据,无需针对不同的数据类型开发不同的方案。这使得

    2024年02月03日
    浏览(89)
  • 带你玩转三子棋—【C语言】

    目录 前言: 1. 菜单的打印 2. game函数的实现 2.1 初始化棋盘 2.2 显示棋盘 2.3 玩家下棋 2.4 电脑下棋 2.5 判断输赢 2.6 判断棋盘是否满了 3. 全部代码 3.1 game.h 3.2  game.c 3.3 test.c 为了实现三子棋,首先我们应该将代码分模块编写,我们分为3个部分 1. test.c —测试游戏(主函数)2

    2024年02月04日
    浏览(47)
  • 带你玩转单向链表(学习必备)

    本篇文章主要介绍数据结构中 单向链表 各种操作,适合有 C语言基础 的同学,文中描述和代码示例很详细,干货满满,感兴趣的小伙伴快来一起学习吧! ☀️大家好!我是新人博主朦胧的雨梦,希望大家多多关照和支持😝😝😝 🌖大家一起努力,共同成长,相信我们都会

    2024年02月02日
    浏览(49)
  • 【Apache-Flink零基础入门】「入门到精通系列」手把手+零基础带你玩转大数据流式处理引擎Flink(特点和优势分析+事件与时间维度分析)

    本文介绍了Apache Flink的定义、架构、基本原理,并辨析了大数据流计算相关的基本概念。同时回顾了大数据处理方式的历史演进以及有状态的流式数据处理的原理。最后,分析了Apache Flink作为业界公认为最好的流计算引擎之一所具备的天然优势,旨在帮助读者更好地理解大数

    2024年02月03日
    浏览(61)
  • Python | 带你玩转Python的各种文件操作

    本篇文章主要介绍Python的各种文件操作,适合刚入门的小白或者对于文件操作基础不太牢固的同学,文中描述和代码示例很详细,看完即可掌握,感兴趣的小伙伴快来一起学习吧。 ☀️大家好!我是新人小白博主朦胧的雨梦,希望大家多多关照和支持😝😝😝 🌖大家一起努

    2023年04月11日
    浏览(72)
  • 【Linux】32条指令带你玩转 Linux !

    目录 1,whoami 2,who 3,pwd 4,ls 1,ls  2,ls -l 3,ls -a 4,ls -al 5,ls -d  6,ls -ld 5,clear 6,cd 1,cd  2,cd . 3,cd .. 4,cd /home/litao/linux/  绝对路径 5,cd ../day02/   相对路径 6,cd ~ 7,cd - 7,tree 8,touch 9,mkdir 1,mkdir 2,mkdir -p 10,rmdir rm 1,rmdir 2,rm 3,rm -f 4,rm -r 5,rm -rf 6,

    2024年02月08日
    浏览(56)
  • 【C语言】带你玩转库函数qsort

    君兮_的个人主页 勤时当勉励 岁月不待人 C/C++ 游戏开发 Hello,米娜桑们,这里是君兮_,之前更新的一直是比较基础和简单的内容,随着博主自己的水平的提升,今天给大家带来点不一样的东西,我们今天要讲的是库函数qsort的用法 废话不多说,咱们直接开始吧! 很多人可能是

    2024年02月16日
    浏览(40)
  • 内网穿透技术 - 带你玩转Ngrok和NATAPP

    使用内网穿透技术,我们出差或者在家,就可以直接访问到公司的电脑或者内网网站,实现远程办公。也可以将我们自己在局域网内搭建的网站暴露出去,让所有人都可以直接访问到。 本文章主要介绍下内网穿透工具Ngrok和NATAPP。 Ngrok 开源,老牌穿透工具 NATAPP 免费隧道,提

    2024年02月15日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包