字符和字符串的库函数C进阶

Posted 林慢慢i

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符和字符串的库函数C进阶相关的知识,希望对你有一定的参考价值。

前言:本章重点介绍字符和字符串的库函数使用,C语言本身是没有字符串类型的,字符串通常存放在常量字符串或字符数组中。字符串常量适用于那些对它不做修改的字符串函数。


在这里插入图片描述



1.strlen

作用介绍:求字符串长度(不包含\\0)

在这里插入图片描述

程序1(自行判断下输出结果)

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

输出:

模拟实现strlen

方式1(临时变量计数器方式):
int my_strlen(const char* str)
{
	int count = 0;
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}
方式2(不创建临时变量计数器):
int my_strlen(const char* str)
{
	int count = 0;
	while (*str)
	{
		count++;
		str;
	}
	return count;
}
方式3(指针方式):
int my_strlen(const char* str)
{
	char* p = str;
	while (*p != '\\0')
	{
		p++;
	}
	return p - str;
}


2.strcpy

作用介绍:拷贝字符串

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

模拟实现

char* my_strcpy(char* dest, const* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while ((*dest = *src))
	{
		;
	}
	return ret;
}


3.strcmp

作用介绍:比较两个字符串是否相等,若字符相同则返回0

在这里插入图片描述

模拟实现

int my_strcmp(char* str1, char* str2)
{
	assert(str1 && str2);
	while (*str1 == *str2)//判断字符是否相等
	{
		if (*str2 == '\\0')//判断是否字符str2结束
		{
			return 0;
		}
		else
		{
			str1++;
			str2++;
		}
	}
	if (*str1 > *str2)
	{
		return 1;
	}
	if (*str1 < *str2)
	{
		return -1;
	}
}


4.strcat

功能介绍:将source所指向的字符串追加到destination所指向的字符串后。

在这里插入图片描述

模拟实现

char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);
	char* ret = dest;//用ret记录dest的首地址,方便后续返回
	while (*dest != '\\0');
	{
		dest++;
	}
	while (*dest++ = *src++)//将src指向的字符串拷到dest后边
	{
		;
	}
	return ret;
}


5.strstr

功能介绍:判断str2是否在str1中出现,即str2是否为str1的子串,若是,则返回str2在str1中首次出现的字符地址,否则返回NULL。

案例:

int main()
{
	char str1[] = "abbbcdef";
	char str2[] = "bbc";
	printf("%s", strstr(str1, str2));
	return 0;
}

在这里插入图片描述

模拟实现

引入三个临时变量,下图中s1与s2就是我们分别指向进行比较的两个字符串(需要移动),首先比较判断s2是否与s1相同,cp用来记录当前比较的第一个字符的位置,遍历cp即可比较str2是否在str1中出现。

在这里插入图片描述

char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	char* s1 = NULL;//不改变str1和str2的指向
	char* s2 = NULL;//保留模式串str2
	char* cp = (char*)str1;
	while (*cp)//cp遍历str1
	{
		s1 = cp;
		s2 = (char*)str2;
		while (*s1 == *s2 && *s1 && *s2)
		{
			s1++;
			s2++;
			if (*s2 == '\\0')//s2遍历
				return cp;
		}
		cp++;
	}
	return NULL;
}


6.strncpy

功能介绍:将source所指向的字符串中num个字符拷贝到destination所指向的字符串中。

在这里插入图片描述

模拟实现

char* my_strncpy(char* dest, const char* src, size_t num)
{
	assert(dest && src);
	char* cp = dest;
	while (num && (*cp++ = *src++))//将src字符串中的num个字符拷贝到cp中
	{
		num--;
	}
	while (num)//若num人大于0,则将cp中接下来的num个字符置为'\\0'
	{
		*cp++ = '\\0';
		num--;
	}
	return dest;
}


7.strncat

功能介绍:在destination所指向的字符串末尾加上num个source所指向的字符串的字符。

在这里插入图片描述

模拟实现

char* my_strncat(char* str1, const char* str2, size_t num)
{
	assert(str1 && str2);
	char* cp = str1;
	while (*cp)//cp遍历str1至'\\0'
	{
		cp++;
	}
	while (num--)//将str2中num个字符拷贝到str1中,若num大于str2字符串长度,则将str1之后的一个字符置为'\\0'
	{
		*cp++ = *str2++;
		if (*str2 == '\\0')
			return str1;
	}
	*cp = '\\0';
	return str1;
}


8.strncmp

在这里插入图片描述

模拟实现

int my_strncmp(const char* str1, const char* str2, size_t num)
{
	assert(str1 && str2);
	while (*str1 == *str2 && num)//str1与str2相等或num不为0是进入循环
	{
		str1++;
		str2++;
		num--;
		if (*str2 == '\\0' || num == 0)//num等于0或str2与str1已比较完成说明二者相同,返回0
			return 0;
	}
	if (*str1 > *str2)
		return 1;
	else
		return -1;
}


9.strtok

功能介绍:

在这里插入图片描述

例子

int main()
{
	char str[] = "150434346@qq.com";
	char* sep = "@.";
	char tmp[30];
	char* cp = NULL;
	strcpy(tmp, str);//将str拷贝一份到tmp中,避免strtok将str中的数据修改
	for (cp = strtok(tmp, sep); cp; cp = strtok(NULL, sep))
	{
		printf("%s\\n", cp);
	}
	return 0;
}

在这里插入图片描述



10.strerror

功能介绍:返回错误码所对应的错误信息。

在这里插入图片描述

strerror函数的应用在判断一些操作的错误类型时能起到很好的效果,比如在程序未达到预期的效果时,可以通过strerror来判断错误的原因,比如:想打开text.txt文件时,没用达到预期效果,可以调用该函数来查找原因。

例子

#include <errno.h>
int main()
{
	FILE* pFile;
	pFile = fopen("unexist.ent", "r");
	if (pFile == NULL)
		printf("文件 不存在:%s\\n", strerror(errno));
	return 0;
}

在这里插入图片描述



11.memcpy

功能介绍

在这里插入图片描述

模拟实现

void* my_memcpy(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);

	while (num--)//4 3 2 1
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}


12.memcmp

功能介绍:

在这里插入图片描述

例子:

int main()
{
	float arr1[] = { 1.0, 2.0,3.0,4.0 };
	float arr2[] = { 1.0, 3.0 };
	int ret = memcmp(arr1, arr2, 8);
	//memcmp - strcmp
	printf("%d\\n", ret);
	return 0;
}

在这里插入图片描述



13.memmove

功能介绍:

在这里插入图片描述

测试例子

int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };

	memmove(arr1, arr1+2, 20);
    
	return 0;
}

在这里插入图片描述

模拟实现

void* my_memmove(void* dest, const void*src, size_t num)
{
	void* ret = dest;
	assert(dest && src);

	if (dest < src)
	{
		//前->后
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else 
	{
		//后->前
		while (num--)//19
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return ret;
}

注释:memmove函数的模拟实现要小心指针所指向内容(数组)被覆盖的问题。

字符和字符串的库函数部分到此介绍结束了,感谢您的阅读!!!如果内容对你有帮助的话,记得给我三连(点赞、收藏、关注)——做个手有余香的人。

以上是关于字符和字符串的库函数C进阶的主要内容,如果未能解决你的问题,请参考以下文章

C语言进阶之旅(12)搞定字符串和内存函数

整型转换字符串的库函数 C语言

C语言进阶笔记深入了解进阶指针

C语言进阶笔记深入了解进阶指针

C语言进阶笔记深入了解进阶指针

C语言进阶笔记深入了解进阶指针