常见关于数组的函数的介绍

关于字符串函数的介绍

求字符串长度

strlen函数

用于计算字符串的长度的函数,需要使用的库函数是string.h

函数声明
size_t strlen(const char *str)
函数模拟实现
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* arr)
{
	assert(arr);
	int len = 0;
	while (*arr)
	{
		len++;
		arr++;
	}
	return len;
}
int main()
{
	char* arr = "asdf";
	printf("%d",my_strlen(arr));

	return 0;
}
#include<stdio.h>
#include<string.h>
int main()
{
	char* arr = "asdf";
	printf("%d", strlen(arr));

	return 0;
}

在这里插入图片描述

需要注意的是:计算的位置并不是随意的,他会计算到’\0’停止并且’\0’不计入字符总长度
在这里插入图片描述
请看这个代码,为什么会出现这中结果呢?你不是说计算到‘\0’结束吗,现在没有’\0’,可是为什么会出现相同的结果呢???
在这里插入图片描述
我们能看到内存中除了已经存好的字符之外全是’\0’,这就是为什么会是4,但是为什么会全是’\0’,因为这是c语言的规则,如果数组进行了初始化但是是未完全的初始化,那么其余的空间都将会被初始化为0

长度不受限制的字符串

strcpy()

使用的时候需要引用string.h头文件
字符串拷贝以’\0’字符为结束标志,拷贝长度不受限制,使用时需要引用库函数—string.h

函数定义
char *strcpy(char *dest, const char *src)
函数模拟实现
char* my_strcpy(char* des, const char* src)
{
	assert(des && src);
	char* res = des;

	while (*des++ = *src++);

	return res;
}

在实现的时候一定要注意将源字符串中的’\0’拷贝进去,不然会出错
未将'\0'拷贝造成错误

strcat

使用的时候需要引用string.h头文件
字符串连接函数

函数声明
char *strcat(char *dest, const char *src)

将后一个字符串放到前一个字符串的末尾,所以需要保证前一个字符串有’\0’结尾,并且写入的时候需要预留足够的空间

函数模拟实现
char* my_strcat(char* des, const char* arr)
{
	assert(des && arr);
	char* res = des;

	while (*des)des++;
	while (*des++ = *arr++);

	return res;
}

运行成功
特别需要强调的就是预留足够的空间
如果将代码写成指针的形式,那就错了!!!
因为指针没有足够的空间

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcat(char* des, const char* arr)
{
	assert(des && arr);
	char* res = des;

	while (*des)des++;
	while (*des++ = *arr++);

	return res;
}
int main()
{
	char* arr = "hello ";
	char* arr2 = "world!";
	my_strcat(arr, arr2);
	puts(arr);
	return 0;
}

strcmp

使用的时候需要引用string.h的头文件
字符串比较函数,比较到有结果或者结尾停止

函数声明
int strcmp ( const char * str1, const char * str2 );

此函数是使用字典序来进行比较大小的,如果a和b比较大小就是那a的ASCII码-b的ASCII码,然后进行返回(需要特殊说明的是,一般情况下返回的是不能于0的数)

函数模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strcmp(const char* arr1, const char* arr2)
{
	assert(arr1 && arr2);
	while (*arr1 || *arr2)
	{
		if (*arr1 != *arr2) return *arr1 - *arr2;
		arr1++;
		arr2++;
	}
	return 0;
}

运行结果

字符长度受限

strncpy,strncat,strncmp

使用的时候需要引用string.h头文件
这些函数与上面的使用方法相似,这里我们之介绍一个—strncpy

函数声明
char * strncpy ( char * destination, const char * source, size_t num );

当num小于source的长度–>拷贝都最后
num小于source的情况

当num大于source的长度–>在结尾的时候加上’\0’
num大于source的情况

字符查找

strstr

函数声明
char *strstr(const char *haystack, const char *needle)

使用的时候需要引用string.h头文件
用于查找字符串中needle字符串第一次出现的位置,如果有—>返回位置

找到了第一次出现的位置
如果没有—>返回NULL指针
没有找到相应的字符串

strtok

函数声明
char *strtok(char *str, const char *delim)

分割字符串函数,delim是分隔符的数组

int main()
{
	char str[] = "asdf-asdfw.asdf-svs";
	char delim[5]="-.";
	
	//使用源字符串会改变源字符串,所以不能使用源字符串
	char arr[100];
	strcpy(arr,str);
	//char* ch = strtok(str, delim);
	for (char* ch = strtok(arr, delim);ch!=NULL;ch=strtok(NULL,delim))
	{
		puts(ch);
	}
	return 0;
}

第一个参数为NULL的时候,计算机中会有一个记录上一次到达的位置,会从这个位置开始向后搜索
运行结果

strerror

使用的时候需要引用errno.h头文件
当调用库函数的时候发生错误时,错误信息会记录到errno的全局变量中

#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
	//当调用库函数发生错误,noerror会记录发生错误的原因
	FILE* pf = fopen("en.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
	}
	return 0;
}

运行结果

内存操作函数

memcpy

使用需要引用string.h头文件
在字节的层面进行复制

函数声明
void *memcpy(void *str1, const void *str2, size_t n)
函数模拟实现
void* my_memcpy(void* des, const void* src, int n)
{
	assert(des && src);
	void* res = des;

	for (int i = 0; i < n; i++)
	{
		*((char*)des + i) = *((char*)src + i);
	}

	return res;
}

运行结果
当我们想将1,2,3,4,5复制成1,2,1,2,3
但是结果却和我们想的不一样
运行错误
分析
为了解决上面的覆盖的问题,就有了下面的函数

memmove

C 库函数 void memmove(void str1, const void str2, size_t n) 从 str2 复制 n 个字符到 str1,但是在重叠内存块这方面,memmove() 是比 memcpy() 更安全的方法。如果目标区域和源区域有重叠***的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同。

函数声明
void *memmove(void *str1, const void *str2, size_t n)
函数模拟实现
void* my_memmove(void* des, const void* src, int n)
{
	assert(des && src);
	void* res = des;

	if (des < src)
	{
		for (int i = 0; i < n; i++)
		{
			*((char*)des + i) = *((char*)src + i);
		}
	}
	else
	{
		while (n--)
		{
			*((char*)des + n) = *((char*)src + n);
		}
	}

	return res;
}

这样子的话是不是就是对了了呢
运行结果

多多练习

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值