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

字字符串函数

1.strlen函数

size_t strlen(const char* str);
功能:计算指针str指向的字符串的字符个数

字符串以'\0'作为结束标志,strlen函数返回的是字符串中'\0'前面出现的字符个数(不包括'\0')

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

注意函数的返回值是size_t

模拟实现

c 复制代码
size_t m_strlen(const char* str)
{
	int count = 0;
	while (*str++)
	{
		count++;
	}
	return count;
}

int main()
{
	char arr[] = "asdfgh";
	int ret = m_strlen(arr);
	printf("%d\n", ret);

	return 0;
}

2.strcpy函数

char* strcpy(char* destination, const char* source);
功能:将指针source指向的字符串的内容拷贝到指针destination指向的字符串里

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

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

目标空间必须大,以确保能存放源字符串

目标空间必须是可修改的(比如:char * p = "xxxxxxxxx";这里的字符串是常量,不能被修改)

模拟实现

c 复制代码
char* m_strcpy(char* str1, const char* str2)
{
	char* tmp = str1;
	while (*str2)
	{
		*str1++ = *str2++;
	}
	return tmp;
}

int main()
{
	char arr1[10] = "abcde";
	char arr2[] = "qwer";
	char* p = m_strcpy(arr1, arr2);
	printf("%s\n", p);

	return 0;
}

3.strcat函数

char* strcat(char* destination,const* source);
功能:将指针source指向的字符串的内容拷贝到指针destination指向字符串的第一个出现字符'\0'的位置

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

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

目标空间必须可以修改

模拟实现

c 复制代码
char* m_strcat(char* str1, const char* str2)
{
	char* tmp = str1;
	while (*str1)
	{
		str1++;
	}
	while (*str2)
	{
		*str1++ = *str2++;
	}
	return tmp;
}

int main()
{
	char arr1[10] = "abcde";
	char arr2[] = "qwer";
	char* p = m_strcat(arr1, arr2);
	printf("%s\n", p);

	return 0;
}

4.strcmp函数

int strcmp(const char* str1, const char* str2);
功能:比较两个字符串的大小

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

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

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

模拟实现

c 复制代码
nt m_strcmp(const char* str1, const char* str2)
{
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	return *str1 - *str2;
}

int main()
{
	char arr1[] = "abac";
	char arr2[] = "abad";
	int ret = m_strcmp(arr1, arr2);
	printf("%d\n", ret);

	return 0;
}

5.strstr函数

char* strstr(const char* str1, const char* str2);
功能:返回 字符串2第一次出现在字符串1中第一个字符的位置,若找不到,返回null

模拟实现

c 复制代码
char* m_strstr(const char* str1, const char* str2)
{
	char* cp = str1;
	char* s1 = cp;
	char* s2 = str2;
	while (*cp)
	{
		s1 = cp;
		s2 = str2;
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2=='\0')
			return cp;
		cp++;
	}
	return NULL;
}

int main()
{
	char arr1[] = "abbbcdef";
	char arr2[] = "bbce";
	char* p = m_strstr(arr1, arr2);
	if (p == NULL)
		printf("没找到");
	else
		printf("找到了");

	return 0;
}

6.strtok函数

char* strtok(char* str, const char* delimiters);
功能:在字符串1中寻找字符串2中的字符,若遇到,则替换成空字符并标记这个位置,最终返回字符串1的地址
此时打印该字符串只能打印到空字符的位置
若想打印后面的字符串,需在再次调用该函数,并且传的参数应为NULL和字符串2

应用

c 复制代码
#include<string.h>
int main()
{
	char arr1[] = "192.192.55.0";
	char copy[30];
	strcpy(copy, arr1);
	char arr2[] = ".";

	char* ret = NULL;
	for (ret = strtok(copy, arr2); ret != NULL; ret = strtok(NULL, arr2))
	{
		printf("%s ", ret);
	}

	return 0;
}

7.strerror函数

char* sterror(int errnum);
功能:返回错误码所对应的错误信息(的地址)

库函数在执行中,发生了错位,会将一个错误码存放在errno这个变量中,errno是C语言提供的一个全局变量

比如:0 1 2 3 4 5...这些数在内存中对应不同的错误信息

c 复制代码
#include<string.h>
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
	}
	else
	{
		printf("成功打开");
	}
	//printf("%s\n", strerror(0));
	//printf("%s\n", strerror(1));
	//printf("%s\n", strerror(2));
	return 0;
}

关于内存的函数

1.memcpy函数

void* memcpy(void* destination, const void* scoure, size_t num);
功能:从source的位置开始赋值num个字节的数据到destination的内存位置,返回目的空间的起始位置

处理不相关,不重叠的内存

任何类型都可以实现该功能

模拟实现

c 复制代码
void* m_memcpy(void* dest, const void* scr, size_t num)
{
	void* tmp = dest;
	while (num--)
	{
		*(char*)dest = *(char*)scr;
		dest = (char*)dest + 1;
		scr = (char*)scr + 1;
	}
	return tmp;

}
int main()
{
	int arr1[] = { 1,2,3,4,5,6 };
	int arr2[] = { 7,8,9,10 };
 这里不能实现arr1+2向arr1中的内存替换
	int* p = m_memcpy(arr1, arr2, 8);
	for (int i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++)
	{
		printf("%d\n", arr1[i]);
	}

	return 0;
}

2.memmove函数

void* memcpy(void* destination, const void* scoure, size_t num);

memcpy函数的升级版,可以实现重叠内存的拷贝

模拟实现

c 复制代码
void* m_memmove(void* dest, const void* scr, size_t num)
{
	void* tmp = dest;
	if (dest < scr)
	{
		//前
		while (num--)
		{
			*((char*)dest) = *((char*)scr);
			dest = (char*)dest + 1;
			scr = (char*)scr + 1;
		}
		
	}
	if (dest > scr)
	{
		//后
		while (num--)
		{
			*((char*)dest + num) = *((char*)scr + num);
		}

	}
	return tmp;
	
}

int main()
{
	int arr1[] = { 1,2,3,4,5,6 };
	int* p = m_memmove(arr1+2, arr1, 8);
	for (int i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++)
	{
		printf("%d\n", arr1[i]);
	}

	return 0;
}
相关推荐
粟悟饭&龟波功7 小时前
Java—— ArrayList 和 LinkedList 详解
java·开发语言
冷雨夜中漫步7 小时前
Java中如何使用lambda表达式分类groupby
java·开发语言·windows·llama
a4576368768 小时前
Objective-c Block 面试题
开发语言·macos·objective-c
Cai junhao8 小时前
【Qt】Qt控件
开发语言·c++·笔记·qt
uyeonashi8 小时前
【QT系统相关】QT网络
开发语言·网络·c++·qt
不过四级不改名6779 小时前
用c语言实现简易c语言扫雷游戏
c语言·算法·游戏
程序猿小D9 小时前
第27节 Node.js Buffer
linux·开发语言·vscode·node.js·c#·编辑器·vim
武昌库里写JAVA9 小时前
【微服务】134:SpringCloud
java·开发语言·spring boot·学习·课程设计
yaoxin52112310 小时前
105. Java 继承 - 静态方法的隐藏
java·开发语言·jvm
我命由我1234510 小时前
嵌入式 STM32 开发问题:烧录 STM32CubeMX 创建的 Keil 程序没有反应
c语言·开发语言·c++·stm32·单片机·嵌入式硬件·嵌入式