文章目录
一、引言
二、函数的介绍与模拟实现
2、1 求字符串长度strlen()函数
2、1、1 strlen()函数介绍
2、1、2 strlen()函数的模拟实现
2、2 字符串拷贝strcpy()函数
2、2、1 strcpy()函数的介绍
2、2、2 strcpy()函数的模拟实现
2、3 字符串追加strcat()函数
2、3、1 strcat()函数的介绍
2、3、2 strcat()函数的模拟实现
2、4 字符串比较strcmp()函数
2、4、1 strcmp()函数的介绍
2、4、2 strcmp()函数的模拟实现
2、5 字符串查找strstr()函数
2、5、1 strstr()函数的介绍
2、5、2 strstr()函数的模拟实现
2、6 内存拷贝memcpy()函数
2、6、1 memcpy()函数的介绍
2、6、2 memcpy()函数的模拟实现
2、7 可对覆盖内存拷贝memmove()函数
三、总结
标题:字符串函数介绍
作者:@Ggggggtm
寄语:与其忙着诉苦,不如低头赶路,奋路前行,终将遇到一番好风景
一、引言
C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。字符串常量适用于那些对它不做修改的字符串函数。
那要是我们对字符串想要修改呢?例如复制字符串、字符串比较、字符串拼接等等。这时就用到了C语言的库函数。本篇文章会对高频用到的字符串函数进行详解。
二、函数的介绍与模拟实现
2、1 求字符串长度strlen()函数
2、1、1 strlen()函数介绍
我们先看一下strlen()函数的返回值和参数,如下:
size_t strlen ( const char * str );
由上我们可以看出strlen()函数的参数是const char*,也就是我们要传一个地址。返回值为size_t,是无符号整型。
在使用strlen()函数时,我们需要注意以下几点:
- 字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。
- 参数指向的字符串必须要以 '\0' 结束。
- 注意函数的返回值为size_t,是无符号的( 易错 )。
针对上述的最后一点,我们看如下代码:
#include <stdio.h>
int main()
{
const char*str1 = "abcdef";
const char*str2 = "bbb";
if(strlen(str2)-strlen(str1)>0)
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0;
}
注意strlen()函数的返回值是无符号整型,所以上述代码中strlen(str2)-strlen(str1)的结果不会出现负值的。
当我们熟悉strlen()函数后,我们还应掌握strlen()函数的模拟实现。
2、1、2 strlen()函数的模拟实现
strlen()函数的模拟实现的方式有很多种,我们这里给出较为常见的,也是相对容易理解的三种,代码如下:
//计数器方式
int my_strlen(const char * str)
{
int count = 0;
while(*str)
{
count++;
str++;
}
return count;
}
//不能创建临时变量计数器
int my_strlen(const char * str)
{
if(*str == '\0')
return 0;
else
return 1+my_strlen(str+1);
}
//指针-指针的方式
int my_strlen(char *s)
{
char *p = s;
while(*p != ‘\0’ )
p++;
return p-s;
}
2、2 字符串拷贝strcpy()函数
2、2、1 strcpy()函数的介绍
我们先看一下strcpy()函数的返回值和参数,如下:
char* strcpy(char * destination, const char * source );
由上我们可以看出strcpy()函数的第一个参数是char* destination,是我们要拷贝到的一个地址。第二个参数是const char * source ,是我们要拷贝的字符串地址。返回值为char * ,返回的地址是destination。
在使用strcpy()函数时,我们需要注意以下几点:
- 源字符串必须以 '\0' 结束。
- 会将源字符串中的 '\0' 拷贝到目标空间。
- 目标空间必须足够大,以确保能存放源字符串。
- 目标空间必须可变。
我们看strcpy()函数的模拟实现。
2、2、2 strcpy()函数的模拟实现
//1.参数顺序
//2.函数的功能,停止条件
//3.assert
//4.const修饰指针
//5.函数返回值
//6.题目出自《高质量C/C++编程》书籍最后的试题部分
char *my_strcpy(char *dest, const char*src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while((*dest++ = *src++))
{
;
}
return ret;
}
2、3 字符串追加strcat()函数
2、3、1 strcat()函数的介绍
我们先看一下strcat()函数的返回值和参数,如下:
char * strcat ( char * destination, const char * source );
由上我们可以看出strcat()函数的第一个参数是char* destination,是我们要追加到的一个地址。第二个参数是const char * source ,是我们要追加的字符串地址。返回值为char * ,返回的地址是destination。
在使用strcat()函数时,我们需要注意以下几点:
- 源字符串必须以 '\0' 结束。
- 目标空间必须足够大,以确保能存放源字符串。
- 目标空间必须可变。
我们看strcat()函数的模拟实现。
2、3、2 strcat()函数的模拟实现
char *my_strcat(char *dest, const char*src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while(*dest)
{
dest++;
}
while((*dest++ = *src++))
{
;
}
return ret;
}
2、4 字符串比较strcmp()函数
2、4、1 strcmp()函数的介绍
我们先看一下strcmp()函数的返回值和参数,如下:
int strcmp ( const char * str1, const char * str2 );
由上我们可以看出strcmp()函数的两个参数就是我们要比较的两个字符串的地址。返回值为int。
在使用strcmp()函数时,我们需要注意以下几点:
- 第一个字符串大于第二个字符串,则返回大于0的数字。
- 第一个字符串等于第二个字符串,则返回0。
- 第一个字符串小于第二个字符串,则返回小于0的数字。
我们看strcmp()函数的模拟实现。
2、4、2 strcmp()函数的模拟实现
int my_strcmp (const char * src, const char * dst)
{
int ret = 0 ;
assert(src != NULL);
assert(dest != NULL);
while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
++src, ++dst;
if ( ret < 0 )
ret = -1 ;
else if ( ret > 0 )
ret = 1 ;
return ret;
}
2、5 字符串查找strstr()函数
2、5、1 strstr()函数的介绍
我们先看一下strstr()函数的返回值和参数,如下:
char * strstr ( const char *str1, const char * str2);
由上我们可以看出strstr()函数的第一个参数是我们要在字符串中查找的地址。第二个参数是要查找的字符串的地址。返回值为char * ,返回的地址是要在字符串中查找到的地址。
我们看strstr()函数的模拟实现。
2、5、2 strstr()函数的模拟实现
char * strstr (const char * str1, const char * str2)
{
char *cp = (char *) str1;
char *s1, *s2;
if ( !*str2 )
return((char *)str1);
while (*cp)
{
s1 = cp;
s2 = (char *) str2;
while ( *s1 && *s2 && !(*s1-*s2) )
s1++, s2++;
if (!*s2)
return(cp);
cp++;
}
return(NULL);
}
2、6 内存拷贝memcpy()函数
2、6、1 memcpy()函数的介绍
我们先看一下memcpy()函数的返回值和参数,如下:
void * memcpy ( void * destination, const void * source, size_t num );
由上我们可以看出memcpy()函数第一个参数是void* destination,是我们要拷贝到的一个地址。第二个参数是const void* source ,是我们要拷贝的字符串地址。返回值为void*,返回的地址是destination。
在使用memcpy()函数时,我们需要注意以下几点:
- 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
- 这个函数在遇到 '\0' 的时候并不会停下来。
- 如果source和destination有任何的重叠,复制的结果都是未定义的。
我们看memcpy()函数的模拟实现。
2、6、2 memcpy()函数的模拟实现
void * memcpy ( void * dst, const void * src, size_t count)
{
void * ret = dst;
assert(dst);
assert(src);
/*
* copy from lower addresses to higher addresses
*/
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return(ret);
}
2、7 可对覆盖内存拷贝memmove()函数
memmove()函数与memcpy()函数大同小异。只不过memcpy()函数的是实现并不能对覆盖内存拷贝,但是memmove()函数是可以的,我们直接看memmove()函数的模拟实现,代码如下:
void * memmove ( void * dst, const void * src, size_t count)
{
void * ret = dst;
if (dst <= src || (char *)dst >= ((char *)src + count))
{
/*
* Non-Overlapping Buffers
* copy from lower addresses to higher addresses
*/
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}
else
{
/*
* Overlapping Buffers
* copy from higher addresses to lower addresses
*/
dst = (char *)dst + count - 1;
src = (char *)src + count - 1;
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return(ret);
}
三、总结
我们上述对多个函数进行了介绍和模拟实现,都是需要我们重点掌握的,再平常用到的频次也较高。
希望以上内容对你有所帮助,感谢阅读ovo~