登陆

长度不受限的字符串函数

admin 2022-11-24 7人围观 ,发现0个评论

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

前言

       本文介绍一下C语言字符串库函数中长度不受限的字符串函数。

       新手一个,水平比较低,还请包涵。

长度不受限的字符串函数

所在头文件: <string.h> 

     顾名思义,这一类函数对字符串进行操作的时候总是以'\0'为基准进行的,长度往往不受限制,容易造成越界。

strlen函数

相关描述

函数原型:size_t strlen( const char *string );

函数功能:计算字符串长度,直到遇到空字符结束,但不包括空结束字符。

函数说明

     strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。

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

     注意函数的返回值为size_t,是无符号的(易错)。

返回类型:size_t (strlen特有的非负整数类型)

        看看这个,是不是觉得打印出<=?要这么想你就掉进坑里了。

image.png

         strlen返回值是无符号整型,3-6你以为会是-3,实际上并不是,这里可不是有符号整型的计算,它们的补码相减运算后得到的数被认为是无符号数,这里会得到一个很大的正数,必然是>0的。

模拟实现

迭代计数法

size_t MyStrlen(const char* dest) { 	assert(dest != NULL);  	size_t cnt = 0;  	while (*dest != '\0') 	{ 		count++; 		dest++; 	}  	return cnt; } 复制代码

递归计数法

size_t MyStrlen(const char* dest) { 	assert(dest != NULL);  	if (*dest)          return 1 + MyStrlen(dest + 1); 	else          return 0; } 复制代码

指针相减法

size_t MyStrlen(const char* dest) { 	assert(dest != NULL);  	const char* tmp = dest;  	while (*(++dest)); //一直后移直到遇见空字符  	return dest - tmp; } 复制代码

strcpy函数

相关描述

函数原型:char *strcpy( char ***** strDestination , const char ***** strSource );

函数功能:把一个字符串(后面的源字符串)拷贝到另一个字符串(前面的目标字符串)中

函数说明: 源字符串必须以 '\0' 结束。

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

目标空间必须足够大,以确保能存放源字符串。 目标空间必须可变,也就是说不能是字符串字面量。

返回类型:char*

模拟实现

char* MyStrcpy(char* dest, const char* src) { 	assert(dest != NULL); 	assert(src != NULL);  	char* ret = dest;  	while (*dest++ = *src++)//包括了把空字符也拷过去 	{ 		; 	}  	return ret; } 复制代码

strcmp函数

相关描述

函数原型:int strcmp(const char *string1, const char *string2);

函数功能:比较两字符串,实际上是通过字符比较实现的

返回类型:int

     字符比较(character comparison)是指按照字典次序对单个字符或字符串进行比较大小的操作,一般都是以ASCII码值的大小作为字符比较的标准

     字符串比较的时候,字符串的大小是从最左边第一个字符开始比较,大者为大,小者为小,若相等,则继续比较后面的字符;

     比如ABC与ACDE比较,第一个字符相同,继续比较第二个字符,由于第二个字符是后面一个串大,所以不再继续比较,结果就是后面个串大。

     再如ABC与ABC123比较,比较三个字符后第一个串结束,所以就是后面一个串大。

     所以,长度不能直接决定大小,字符串的大小是由左边开始最前面的字符决定的。

注意

     当字符串有空格时,空格也参加比较。

     由汉字组成的字符串可以参加比较。如”李红”<”王军”。它们的大小实际是由其拼音构成的字符串的大小来决定的,即:”LIHONG”<”WANGJUN”。

返回值对应不同的字符串关系

image.png

     其中返回值为0说明两字符串内容完全相同。

模拟实现

int MyStrcmp(const char* str1, const char* str2) {     assert(str1 != NULL);     assert(str2 != NULL);          while(*str1 == *str2)     {         if(*str1 == '\0')             return 0;         str1++;         str2++;     }     return *str1 - *str2;  } 复制代码

strcat函数

相关描述

函数原型:char* strcat(char *strDestination, const char *strSource);

函数功能:字符串追加,就是把一个字符串接到另一个字符串的尾巴上去。

     strcat函数将字符串strSource附加到字符串strDestination后面,并使用空字符终止生成的字符串。strSource的初始字符覆盖strDestination的终止空字符。

函数说明

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

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

     目标空间必须可修改。

     复制或追加字符串时不执行溢出检查。

     字符串自己给自己追加,如何?

     如果源字符串和目标字符串重叠,则strcat的行为未定义。

返回类型:char*

模拟实现

char* MyStrcat(char* dest, const char* src) {     assert(dest != NULL);     assert(src != NULL);          char* ret = dest;      while(*(++dest))     {         ;     }      while(*dest++ = *src++)     {         ;     }          return ret; } 复制代码

strstr函数

相关描述

函数原型:char* strstr( const char *string, const char *strCharSet);

函数功能:在字符串string中寻找第一次出现的子字符串strCharSet,如果找到返回对应地址,如果找不到返回空指针。

返回类型:char*

模拟实现

BF算法(暴力匹配)

前置思考:

     两个指针分别指向总字符串和子字符串,将元素一一进行比对,不相同的话str后移,相同的话str和substr同时后移,直到substr遇到空字符,这时就说明找到了。

     那有没有一种可能,就是说前几个字符都对上了,但是后面的对不上,也就是第一次匹配没匹配上,这时候该怎么处理呢?

image.png

     那就不止设置一个循环。

实现思路

     用cur指针存放当前总字符串指向位置的地址,再用s1,s2两个指针分别对总字符串和子字符串中的字符进行比对,两指针未移动到字符串的末尾的前提下,若是字符相同则移动至下一个再比对,当s2遇到空字符时说明找到了子字符串,此时直接返回cur指针内容。

实现代码:

char* MyStrstr(const char* str, const char* substr) { 	//指针有效性检测 	assert(str != NULL); 	assert(substr != NULL);      const char* s1 = NULL; 	const char* s2 = NULL; 	const char* cur = str;  	//子字符串为空时 	if ('\0' == *substr) 	{ 		return (char* )str; 	}  	while (*cur) 	{ 		s1 = cur; 		s2 = substr; 		while (*s1 && *s2 && *s1 == *s2) 		{ 			s1++; 			s2++; 		} 		if ('\0' ==  *s2) 		{ 			return (char*)cur; 		}  		cur++; 	} 	return NULL;  } 复制代码

请发表您的评论
请关注微信公众号
微信二维码
不容错过
Powered By Z-BlogPHP