【进阶C语言】字符串函数+内存函数

一.字符串函数

1.strlen

功能:求字符串长度(不包括\0)

函数

1.返回类型:无符号的int——size_t
2.函数参数:字符串的首地址(所求的在函数内部,不能发生改变,最好为const,也防止有人迷糊的时候写代码,把代码写的一团糟)

模拟实现:

#include <stdio.h>
#include <assert.h>
size_t  my_strlen(const char*str)
{
	assert(str);
	char* ret = str;
	while (*str++)
	{
		;
	}
	return (str - ret -1);
}
int main()
{
	char str[] = "Geneius";
	printf("%d",my_strlen(str));
	return 0;
}

2.1 strcmp

功能

字符串比较

函数

1.返回类型:有符号的int。

如果相等则返回0。
如果所正在比较的字符相减大于0,返回一个大于0的数。
如果所正在比较的字符相减小于0,返回一个小于0的数。

2.参数

1.要比较的字符串1
2.要比较的字符串2

注意:这里的相减指的是——所正在比较的字符串1的字符减去字符串2的字符。

模拟实现

#include <stdio.h>
#include <assert.h>
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while ((*str1 == *str2)&&*str1&&*str2)
	{
		str1++;
		str2++;
	}
	return *str1 - *str2;
}
int main()
{
	char str[] = "Geneius";
	char str1[] = "Geneis";
	printf("%d", my_strcmp(str, str1));
	return 0;
}

2.2 strncmp

1.这的参数比strcmp多了一个:size_t num(要比较的字节)
2.比strcmp更加安全,因为这比较的字节数是自己设定的,会多想一下。

3.1 strcat

功能

字符串追加

函数

1.返回类型:char *
2.参数:

1.目标字符串的首字母的地址
2.追加的字符串的首字母的地址
注意:
1.源字符串必须以 ‘\0’ 结束。
2.目标空间必须有足够的大,能容纳下源字符串的内容。
3.目标空间必须可修改。
4.字符串不能自己给自己追加

模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(src && dest);
	while (*dest != 0)
	{
		dest++;
	}
	while (*dest++=*src++)
	{
		;
	}
	return ret;
}
int main()
{
	char str[20] = "Geneius";
	char str1[] = "Geneius";
	printf("%s", my_strcat(str, str1));
	return 0;
}

3.2strncat

1.这的参数比strcat多了一个:size_t num(要追加的字节)
2.比strcat更加安全,因为这追加的字节数是自己设定的,会多想一下。
3.如果大于字符串本身的字节数,则与strcat相同。到\0停止,不追加\0.

模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strncat(char* dest, const char* src ,size_t num)
{
	char* ret = dest;
	assert(src && dest);
	while (*dest != 0)
	{
		dest++;
	}

	while ((num--)&&(* dest++ = *src++))
	{
		;
	}
	return ret;
}
int main()
{
	char str[20] = "Geneius\0xxxxxxxx";
	char str1[] = "Geneius";
	printf("%s", my_strncat(str, str1,10));
	return 0;
}

4.1 strcpy

功能

字符串拷贝

函数

1.返回类型:char *
2.参数:

1.源字符串的地址
2.目标字符串的地址
注意:
1.源字符串必须以 ‘\0’ 结束。
2.会将源字符串中的 ‘\0’ 拷贝到目标空间。
3.目标空间必须足够大,以确保能存放源字符串。
4.目标空间必须可变

模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strcpy(char*dest,const char*src)
{ 
	assert(src && dest);
	char* ret = dest;
	while (*dest++=*src++)
	{
		;
	}
	return ret;
}
int main()
{
	char str[20] = "Geneius";
	char str1[20] = { 0 };
	printf("%s", my_strcpy(str1,str));
	return 0;
}

4.2 strncpy

1.这的参数比strcpy多了一个:size_t num(要拷贝的字节)
2.如果多余本身则进行补\0

模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strcpy(char* dest, const char* src,size_t num)
{
	assert(src && dest);
	char* ret = dest;

	while (num--)
	{
		if (*src != 0)
		{
			*dest++ = *src++;
	    }
		else
		{
			*dest++ = 0;
		}
	}
	return ret;
}
int main()
{
	char str[20] = "Geneius";
	char str1[20] = { "xxxxxxxxxxxxxxxxxxx"};
	printf("%s", my_strcpy(str1, str,10));
	return 0;
}

5.strstr

功能

在字符串1中,查找与字符串2具有相同的字符串。

函数

1.返回类型:char*
2.参数

1.字符串1的首字母的地址
2.字符串2的首字母的地址

模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	char* tmp = str1;
	char* tmp1 = str2;
	while (*str2 && *str1)
	{
		//if (*str2++ == *str1++)
		//{
		//	; 
		//}
		//else
		//{
		//	tmp++;
		//	str1 = tmp;
		//	str2 = tmp1;
		//}
		(*str2++ == *str1++) ? 0 : (tmp++, str1 = tmp, str2 = tmp1);
	}
	//if (*str2 == 0)
	//{
	//	return tmp1;
	//}
	//else
	//{
	//	return NULL;
	//}
	return (*str2 == 0) ? tmp : NULL;
}
int main()
{
	char str[20] = "Geneius";
	char* p = "ne";
    printf("%s",my_strstr(str, p));
	return 0;
}

6.strtok

功能

在字符串1中分割出所需的字符串

函数

1.返回类型:char*
2.参数

1.字符串1的首字母的地址
2.字符串2(分割符可以是多个)的首字母的地址

注意:

1.strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
2.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置。
2.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。
3.如果字符串中不存在更多的标记,则返回 NULL 指针。

#include <stdio.h>
#include <string.h>
int main()
{
	
	char arr[20] = { 0 };
	char arr1[20] = { "abc.def@ghi" };
	strcpy(arr, arr1);
	printf("%s\n", arr1);
	char* p = ".@";
	char* ret = NULL;
	for (ret = strtok(arr, p); ret != NULL; ret = strtok(NULL, p))
	{
		printf("%s\n", ret);
	}
	return 0;
}

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

7.strerror

功能

返回错误码对应的错误信息(字符串)

函数

1.返回类型:char*
2.参数:int

#include <stdio.h>
#include <string.h>
int main()
{
	printf("1.%s\n\n", strerror(0));
	printf("2.%s\n\n", strerror(1));
	printf("3.%s\n\n", strerror(2));
	printf("4.%s\n\n", strerror(3));
	printf("5.%s\n\n", strerror(4));
	printf("6.%s\n\n", strerror(5));
	printf("7.%s\n\n", strerror(6));
	printf("8.%s\n\n", strerror(7));
	printf("9.%s\n\n", strerror(8));
	printf("10.%s\n\n", strerror(9));
	return 0;
}

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

二.内存函数

1.memcpy

功能

实现以字节为单位的拷贝(拷贝不重叠的内存)

函数

1.返回类型:void*
2.参数:

1.要拷贝的位置的地址(源头)——const void*
2.被拷贝的目标地址(目标)——void*
3.要拷贝的字节数——size_t
注意:size_t,需要包含头文件(stdio.h)才能使用

模拟实现

#include <stdio.h>
#include <assert.h>
void* my_mecpy(void *dest,const void *sour, size_t num)
{
	assert(dest && sour);
	while (num--)
	{
		*(char*)dest = *(char*)sour;
		++((char*)dest);
		++((char*)sour);
	}
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 0 };
	int sz = sizeof(arr1);
	my_mecpy(arr2, arr1, sz);
	return 0;
}

2.memmove

功能

实现以字节为单位的拷贝(拷贝重叠的内存)

函数

1.返回类型:void*
2.参数:

1.要拷贝的位置的地址(源头)——const void*
2.被拷贝的目标地址(目标)——void*
3.要拷贝的字节数——size_t
注意:size_t,需要包含头文件(stdio.h)才能使用
在这里插入图片描述

模拟实现

void my_memove(void* dest, const void* sour, size_t num)
{
	assert(dest && sour);
	if (dest>sour)
	{
		//找到拷贝的最后一个字节的地址
		sour = (char*)sour + num -1;
		dest = (char*)dest + num -1;
		while (num--)
		{
			*(char*)dest = *(char*)sour;
			--((char*)dest);
			--((char*)sour);
		}
	}
	else
	{
		while (num--)
		{
			*(char*)dest = *(char*)sour;
			++((char*)dest);
			++((char*)sour);
		}
	}
}

4.memcmp

功能

实现以字节为单位的比较

函数

1.返回类型:int
2.参数:

1.要比较的字符串1的地址——const void*
2.要比较的字符串2的地址——const void*
3.要比较的字节数——size_t
注意:size_t,需要包含头文件(stdio.h)才能使用
标准规定:如果比较的字节数相等则返回0,如果字符串1要比较的字节大于字符串2的返回大于0的数,反之返回一个小于0的数。

5.memset

功能

实现以字节为单位的设初值

函数

1.返回类型:void*
2.参数:

1.目标空间的起始地址——void*
2.要设置的值——int
3.要设置的字节数——size_t
注意:所传的地址不为空

  • 17
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值