目录
1:strlen函数
2:strcpy函数
3:strcmp函数
4:strcat函数
5:strstr函数
前言:
本章将会详细讲解几个常用的字符串函数,并且会模拟实现它工作的原理->
功能:求解字符串中'\0'字符前面的个数,不包含'\0'。
使用语法:strlen(const char*p),括号里面的为一个字符串的地址,返回值为无符号整形的数字
注意点:->返回值,下面我们来看一段易错代码
int main()
{
if (strlen("abc") - strlen("abcdef") < 0)
{
printf("哈哈\n");
}
else
{
printf("呵呵\n");
}
return 0;
}
//这里的结果是啥呢?
不难算出 字符串长度为 3-6 所以应该是-3 所以打印哈哈?
让我们揭晓答案吧
没错:它打印的是呵呵,为啥呢?
应为strlen函数的返回值为无符号整形,所以尽管我们算出来了两个数相减得到的是-3,可是因为返回值类型是个无符号,所以我们的计算机会将-3的补码认为是一个无符号整形,所以算出来是一个很大的数。
关于strlen函数的模拟实现-->
其实有3种方法:
法1:
思路:使用计数器的方式
当我们的指针所指向的元素不是'\0'的时候,计数器++,直到找到'\0'
size_t my_strlen(const char* p)
{
int count = 0;
while (*p != '\0')
{
count++;
p++;
}
return count;
}
int main()
{
char arr[] = "abcdefgh";
size_t ret = my_strlen(arr);
printf("%u\n", ret);
}
法2:
思路:我们可以利用指针-指针的方式来实现,因为我们知道在相同类型的指针相减得到的是两个指针之间含有元素的个数。
size_t my_strlen(const char* p)
{
char* begin = p;//先标记起始位置的地址
while (*p != '\0')//通过循环找到'\0'的地址
{
p++;
}
return p - begin;//随着下标的增加数组的地址也是增加的
}
int main()
{
char arr[] = "abcdefgh";
size_t ret=my_strlen(arr);
printf("%u\n", ret);
return 0;
}
法3:
思路:通过递归的形式来模拟实现strlen
size_t my_strlen(char* p)
{
if (*p == '\0')
return 0;
else
return 1 + my_strlen(p + 1);
}
int main()
{
char arr[] = "abcdef";
size_t ret=my_strlen(arr);
printf("%u", ret);
return 0;
}
功能:拷贝字符串
使用语法:strcpy(char* dest,const char* src),是将src所指向的字符串的内容拷贝到dest所指向的字符串中。返回dest的地址
注意点:
1:目标地址所指向的空间大小一定要比src所指向的空间大
2:会将src所指向的字符串中'\0'也拷贝过来,也就是说src字符串一定要存在'\0'
3:目标字符串一定要可变,即不能用const来修饰,因为目标字符串需要改变
strcpy函数的实现-->
思路:我们用两个指针分别指向两个字符串,然后通过循环改变目的地字符串中的内容,包括’\0'也要拷贝
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest;//应为dest指针是会变的,而我们却要返回目的地的地址
assert(dest && src);//保证指针的准确性
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
*dest = '\0';
// 上面的可以简化为--> while (*dest++=*src++)
{
;//当*src为'\0'时,还会先赋值在,不执行循环
}
return ret;
}
int main()
{
char arr1[20] = "xxxxxxxxxxxxxxxx";
char arr2[] = "hello tomorrow";
my_strcpy(arr1, arr2);
printf("%s", arr1);
return 0;
}
作用:比较两个字符串中每个字符的asc码值,如果str1大于str2则返回大于0的数,两个字符串相等则返回0,小于则返回一个小于1的数
使用语法:strcmp(const char* str1,const char* str2);
strcmp函数的模拟实现-->
思路: 分别比较每个字符,如果相等就比较下一对,直到比到'\0'
int my_strcmp(const char* p1,const char* p2)
{
while (*p1 ==*p2 )
{
if (*p1 == '\0')
return 0;
p1++;
p2++;
}
if (*p1 > *p2)
return 1;
else
return -1;
}
int main()
{
char str1[] = "bbcdefgh";
char str2[] = "abcdefgh";
int ret =my_strcmp(str1, str2);
if (ret == 0)
{
printf("str1等于str2\n");
}
else if (ret < 0)
{
printf("str1小于str2\n");
}
else
{
printf("str1大于str2\n");
}
return 0;
}
作用:拼接字符串函数,可以将一个字符串中的内容拼接到另外一个字符串中
使用语法:strcat(char*dest,const char* src);
strcat函数的模拟实现-->
思路,还是通过指针先找到dest中的'\0'字符,在拷贝src字符串中的内容-->
char* my_strcat(char* dest, const char* src)
{
char* begin = dest;
//先通过循环找到dest的'\0'字符
while (*dest != '\0')
{
dest++;
}
//找到了然后进行拷贝
while (*dest++ = *src++)
{
;
}
return begin;
}
int main()
{
char arr1[20] = "hello ";
char arr2[] = "tomorrow";
//strcat(arr1, arr2);
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
注意:在拼接的时候,要注意目的地的空间一定要足够大。
作用:在一个字符串中寻找字串,并且返回字串在主串中的首元素地址
使用语法:strstr(str1,str2),str1表示主串,str2表示字串,如果找不到则返回null,找到了则返回在主串中的首地址
strstr函数的模拟实现:-->
char* my_strstr(const char* p1, const char* p2)
{
char* move1 = p1;//用来移动的
char* address = p1;//用来保存元素配对时的首元素的位置
char* move2 = p2;
while (*address != '\0')
{
move1 = address;
move2 = p2;
//判断
while (*move1 == *move2&&*move2!="\0"&&*move1!='\0')//确保一趟进行比较
{
move1++;
move2++;
}
if (*move2 == '\0')//当'*move2='\0',则说明找到了
return address;
address++;
}
return NULL;
}
int main()
{
char str1[] = "aabbddef";
char str2[] = "bbdfe";
char* ret =my_strstr(str1, str2);
printf("%s\n", ret);
return 0;
}
讲解-->:
首先通过指针来移动,每个字符比较,如果相等就比较下一个字符即move指针+1,不相等则将move2指针指向开头,address指针(即两个字符串比较开始的地址),加1,move1指针又等于address,当address指针指向'\0'的时候,则说明在字符串中没有找到子字符串,这是暴力求解的方法。
感谢大家的观看!。