【史上最全】C语言:字符串+内存函数的介绍

字符函数和字符串函数可以分为以下几类:

  • 求字符串长度
    strlen
  • 长度不受限制的字符串长度
    strcpy
    strcat
    strcmp
  • 长度受限制的字符串函数介绍
    strncpy
    strncat
    strncmp
  • 字符串查找
    strstr
    strtok
  • 错误信息报告
    strerror
  • 字符操作
  • 内存操作函数
    memcpy
    memmove
    memset
    memcmp

函数介绍
1.strlen

size_t strlen(const char* str)

计数长度以‘\0’作为结束标志,返回‘\0’前出现的字符个数。因此如果返回的字符串无‘\0’将会出现随机数。返回值是size_t,是无符号的。
同时sizeof也可以计数,但其不是函数,是操作数。
模拟实现:

size_t my_strlen(const char* str)
{
	int count = 0;
	// 断言,不满足会报错
	assert(str != NULL);
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}

2.strcpy

strcpy(arr1,arr2)

表示把arr2拷贝到arr1中
arr2必须以‘\0’结尾,并会将’\0’拷贝到目标空间,因此目标空间必须足够大,必须可变,确保能存放源字符串。

//strcpy返回的是目标字符串的起始地址
char* my_strcpy(char* dest, char* str)
{
	assert(dest && str);
	char* ret = dest;
	while (*dest++=*str++)
	{
		;
	}
	return ret;
}

对于数组必须确定个数,不然容易返回随机数。

3.strcat
strcat(arr1, arr2)表示把arr2追加到arr1中,
同样,arr2必须以‘\0’结尾。
模拟实现:

//模拟实现strcat
char* my_strcat(char* dest, char* str)
{
	assert(dest && str);
	char* ret = dest;
	//找'\0'
	while (*dest)
	{
		dest++;
	}
	//拷贝
	while (*dest++ = *str++)
	{
		;
	}
	return ret;
}

4.strcmp
用来比较两个字符串,比较的是对应位置上字符串的大小,如果相同,就比较下一对,指导不同或遇到’\0’
strcmp(arr1, arr2)

  • arr1 > arr2
    返回大于0的数(VS环境下返回1)
  • arr1 = arr2
    返回0(VS环境下返回0)
  • arr1 < arr2
    返回小于0的数(VS环境下返回-1)
    模拟实现:
int my_strcmp(const char* s1, const char* s2)
{
	assert(s1 && s2);
	while (*s1 == *s2)
	{
		if (*s1 == '\0')
		{
			return 0;
		}
		s1++;
		s2++;
	}
	/*if (*s1 > *s2)
	{
		return 1;
	}
	else
	{
		return -1;
	}*/
	return *s1 - *s2;
}

5.strncpy
6.strncat
7.strncmp

使用与前几个相似,唯一不同是可以选择操作的字符数
eg. strncpy(arr1, arr2, n),把arr2中n个字符拷贝到arr1中,若arr2字符串长度小于n,则补0。
其余两个函数类似。
8.strstr
strstr(arr1,arr2)
寻找arr2中包含的arr1子串。
包含,返回arr1子串第一次出现的地址;
若不包换,返回空指针
9.strtok
char* strtok(char* str, const char* sep)
str表示将要被分隔的字符串,sep是用作分隔符的字符合集。
10.strerror
char* strerror(int errnum)
返回错误码所对应的错误信息。
使用时注意包含头文件 #include <errno.h>
会有一个全局变量 errno
若想直接打印可用perror("****")部分自定义,会在打印时表示错误名称。
11.memcpy
void
memcpy(void
destination, const void
source, size_t num)

这个函数在遇到’\0’时不会停下来,若source和dest有任何的重叠,结果未定义
模拟实现:

void* my_memcpy(void* dst,const void* src,size_t count)
{
	assert(dst&&src);
	void* ret = dst;
	while (count--)
	{
		*(char*)dst = *(char*)src;
		dst = (char*)dst + 1;
		src = (char*)src + 1;
	}
	return ret;
}

12.memmove
void* memmove(void* destination, const void* source, size_t num)
与memcpy唯一的区别是处理的源内存块可以重叠。

模拟实现要注意每段复制顺序,不然会有重复(思路如图):
在这里插入图片描述

void* my_memmove(void* dst, const void* src, size_t count)
{
	assert(dst&&src);

	void* ret = dst;
	//从前向后
	if (dst <= src || (char*)dst >= ((char*)src + count))
	{
		while (count--)
		{
			*(char*)dst = *(char*)src;
			dst = (char*)dst + 1;
			src = (char*)src + 1;
		}
	}
	//从后向前
 // //写法一
	//else
	//{
	//	dst = (char*)dst + count - 1;
	//	src = (char*)src + count - 1;

	//	while (count--)
	//	{
	//		*(char*)dst = *(char*)src;
	//		dst = (char*)dst - 1;
	//		src = (char*)src - 1;
	//	}
	//}
  //写法二
	else
	{
		while (count--)
		{
			*((char*)dst + count) = *((char*)src + count);
		}
    }
	return ret;
}

13.memcmp
int memcmp(const void* ptr1, const void* ptr2, size_t num)
一对字节一对字节往后比,无视‘\0’
14.memset
内存设置,以字节为单位初始化
memset(arr, 0, 20)把arr中20个字节改为0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值