飞道的博客

【C语言】常见字符串函数总结及模拟实现

369人阅读  评论(0)

头文件:string.h

strlen

size_t strlen( const char* string )

功能:计算字符串中\0之前的字符的个数,不包括\0。

返回值:字符串中字符的个数。

  • 参数指向的字符串必须要以’ \0 '结束
  • strlen函数返回的是在字符串中’ \0 ‘前面出现的字符个数(不包含’ \0 ')
  • 函数的返回值为size_t,是无符号的(unsigned int)

模拟实现

#include<stdio.h>
#include<assert.h>

//count计数法
unsigned int my_strlen(const char* string)
{
   
    //断言,保证指针的有效性,防止野指针
    assert(string!=NULL);
	unsigned int count = 0;
	while(*string)
	{
   
		count++;
		string++;
	}
	return count;
}

//递归法
unsigned int my_strlen(const char* string)
{
   
    assert(string!=NULL);
	if (*string)
		return 1 + my_strlen(string + 1);
	else
		return 0;
}

//指针-指针法
unsigned int my_strlen(const char* string)
{
   
    assert(string!=NULL);
	//const修饰的安全的指针交给一个不安全的char*的指针是要强制类型转换
	char* tmp = (char*)string;
	while (*string)
	{
   
		string++;
	}
	return string - tmp;
}

int main()
{
   
	char arr[] = "abcdef";
	printf("%d\n", my_strlen(arr));
	return 0;
}

strcpy

char* strcpy(char* destination,const char* source)

功能:拷贝源字符串的内容到另目的地字符串。

返回值:目的地字符串的首字符地址。

  • 源字符串必须以’ \0 '结束
  • 会将源字符串中的’ \0 '也拷贝到目标空间
  • 目标空间必须足够大,以确保能存放源字符串
  • 目标空间必须可变(不能为常量字符串)

模拟实现

#include<stdio.h>
#include<assert.h>

char* my_strcpy(char* dest, const char* src)
{
   
    //断言,保证指针的有效性,防止野指针
	assert(dest != NULL);
	assert(src != NULL);
	//先保存好目的地字符串首元素地址,最后要返回它
	char* tmp = dest;
	while (*dest++ = *src++)
	{
   
		;
	}
	return tmp;
}

int main()
{
   
	char arr1[] = "abcdefg";
	char arr2[] = "hijklmn";
	printf("arr1=%s\n", my_strcpy(arr1, arr2));
	return 0;
}

strcat

char* strcat( char* strDestination, const char* strSource )

功能:拼接字符串。

返回值:目的地字符串的首元素地址。

  • 源字符串必须以 ‘\0’ 结束(最后’ \0 '也会拼接上去)
  • 从目的地字符串’ \0 ‘的位置开始拼接(覆盖目的地字符串的’ \0 ')
  • 目标空间必须可修改(不能为常量字符串)
  • 目标空间必须有足够的大,能容纳下源字符串的内容

模拟实现

#include<stdio.h>
#include<assert.h>

char* my_strcat(char* dest, const char* src)
{
   
	//先保存好目的地字符串首元素地址,最后要返回它
	char* tmp = dest;
	//断言,保证指针的有效性,防止野指针
	assert(dest != NULL);
	assert(src != NULL);
	//找到dest字符串中'\0'的地址
	while (*dest)
	{
   
		dest++;
	}
	//开始拼接(拷贝)
	while (*dest++ = *src++)
	{
   
		;
	}
	return tmp;
}

int main()
{
   
	char arr1[30] = "abcdefg";
	char arr2[] = "hijklmn";
	printf("arr1=%s\n", my_strcat(arr1, arr2));
	return 0;
}

strcmp

int strcmp( const char* string1, const char* string2 )

功能:比较到出现字符不一样或者一个字符串结束或者num个字符全部比较完。

返回值:若str1>str2返回一个大于零的数字;若str1=str2返回0;若str1<str2返回一个小于零的数字。

  • 从头开始一个字符一个字符的比较,若两个字符相等有两种情况1.两个字符都为’ \0 ‘结果返回0;2.相同的非’ \0 '字符那就继续下一个字符的比较。
  • 若比较到两个字符不同,则对应字符ASCLL编码大的所在的字符串更大。

模拟实现

#include<stdio.h>
#include<assert.h>

int my_strcmp(const char* str1, const char* str2)
{
   
	//断言,判断指针的有效性,防止野指针
	assert(str1 != NULL);
	assert(str2 != NULL);
	while (*str1==*str2)
	{
   
		if (*str1 == '\0')//相等的情况
		{
   
			return 0;
		}
		str1++;
		str2++;
	}
	if (*str1 > *str2)
		return 1;
	else
		return -1;
}

int main()
{
   
	char arr1[] = "abcd";
	char arr2[] = "abcz";
	printf("%d\n", my_strcmp(arr1, arr2));
	return 0;
}

strstr

char* strstr( const char* string1, const char* string2 );

功能:在string1中查找是否有string2子串。

返回值:若找到了,返回子串的首元素地址;若没找到,返回空指针。

#include<stdio.h>
#include<assert.h>

char* my_strstr(const char* str1, const char* str2)//const修饰的安全的指针,在赋值给不安全的指针变量和作为返回值时要进行相应的强制类型转换
{
   
    //断言,判断指针的有效性,防止野指针
	assert(str1 != NULL);
	assert(str2 != NULL);
	char* cur = (char*)str1;
	//当需要查找的字符串为空字符串时,返回这个空字符串
	if (*str2 == '\0')
	{
   
		return (char*)str2;
	}
	while (*cur)
	{
   
		//记录匹配的位置
		char* s1 = cur;
		char* s2 = (char*)str2;
		//开始匹配
		while ((*s1 != '\0') && (*s2 != '\0') && (*s1 == *s2))
		{
   
			s1++;
			s2++;
		}
		if (*s2 == '\0')//匹配成功的情况
		{
   
			return cur;
		}
		if (*s1 == '\0')
		{
   
			return NULL;//匹配失败的一种情况,尽早退出(例如abc  abcdef)
		}
		cur++;
	}
	return NULL;//匹配失败,找不到子串
}

int main()
{
   
	char arr1[] = "abbbcdef";
	char arr2[] = "bbc";
	char* ret = my_strstr(arr1, arr2);
	if (ret != NULL)
		printf("找到了:%s\n", ret);
	else
		printf("子串不存在\n");
	return 0;
}


转载:https://blog.csdn.net/m0_51064412/article/details/113816626
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场