目录
strlen
size_t strlen ( const char * str );
- 字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )
- 参数指向的字符串必须要以 ‘\0’ 结束
- 函数的返回值为size_t,是无符号的
strlen("abc") - strlen("abcdef") > 0
原因:
返回值为无符号数,则3-6=-3转换为无符号数为一个很大的正数
比较大小时,直接strlen("abc") > strlen("abcdef")
即可
- 头文件为
#include<string.h>
strlen函数的模拟实现
有三种实现方法my_strlen
(返回类型可以是int
,也可以是size_t
)
无符号数打印用%u
主函数
int main()
{
printf("%d\n", my_strlen("abc"));
return 0;
}
- 计数器的方式
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;
}
strcpy
char* strcpy(char * destination, const char * source );
destination:目的地
source:来源
- 将源指向的字符串复制到目标指向的数组中,包括终止空字符(并在该点停止)
- 源字符串必须以 ‘\0’ 结束
- 会将源字符串中的 ‘\0’ 拷贝到目标空间
- 目标空间必须足够大,以确保能存放源字符串
- 目标空间必须可变
- 头文件为
#include<string.h>
strcpy函数的模拟实现
主函数
int main()
{
char arr1[20] = "xxxxxxxxxxxxxxxxxx";
char arr2[] = "abcdef";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
//printf("%s\n", my_strcpy(arr1, arr2));//简化
return 0;
}
- 返回类型为
char*
是为了实现链式访问- 返回值为目标空间的起始地址
- 防止目标地址和源地址为空指针,保证指针的有效性所以使用
assert
函数进行断言- 目标地址可变,源地址不可变,所以用
const
进行修饰
my_strcpy
函数
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest;
assert(dest != NULL);
assert(src != NULL);
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
*dest = *src;
return ret;
}
循环可以简化
简化后的my_strcpy
函数
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest;
assert(dest != NULL);
assert(src != NULL);
while (*dest++ = *src++)
{
;
}
return ret;
}
strcat
char * strcat ( char * destination, const char * source );
- 将源字符串的副本附加到目标字符串。目标中终止的null字符将被源的第一个字符覆盖,并且null字符将包含在目标中这两个字符串联形成的新字符串的末尾
- 源字符串必须以 ‘\0’ 结束
- 目标空间必须有足够的大,能容纳下源字符串的内容
- 目标空间必须可修改
- 字符串不可以自己给自己追加
- 头文件为
#include<string.h>
strcat函数的模拟实现
主函数
int main()
{
char arr1[20] = "hello";
char arr2[] = " world";
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
my_strcat
函数
#include<assert.h>
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;
}
while (*dest) dest++;
不可以简化为while(*dest++)
原因:
while(*dest++)
循环结束后dest
指向’\0’后一个空间
而my_strcat
函数的源地址需要将目标地址中的’\0’覆盖成它的第一个字符
strcmp
int strcmp ( const char * str1, const char * str2 );
- 将字符串str1与字符串str2进行比较
- 此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续使用以下成对字符,直到字符不同或达到终止的null字符
- 标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字 - 头文件为
#include<string.h>
strcmp 函数的模拟实现
主函数
int main()
{
int ret = my_strcmp("abc", "bbc");
printf("%d\n", ret);
return 0;
}
my_strcmp
函数
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return (*str1 - *str2);
}
当*str1>*str2
时,*str1 - *str2
返回大于0的值
当*str1<*str2
时,*str1 - *str2
返回小于0的值
长度不受限制,重点关注’\0’ ----- strcpy / strcat / strcmp
strncpy
char * strncpy ( char * destination, const char * source, size_t num );
- 拷贝num个字符从源字符串到目标空间
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个
- 目的地和来源不重叠
- 头文件为
#include<string.h>
strncat
char * strncat ( char * destination, const char * source, size_t num );
- 将源的前num个字符追加到目标,再加上一个终止的null字符
- 如果source中的C字符串的长度小于num,则只复制终止null字符之前的内容
- 头文件为
#include<string.h>
strncmp
int strncmp ( const char * str1, const char * str2, size_t num );
- 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完
- 标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字 - 头文件为`#include<string.h>
长度受限制的字符串函数 ----- strncpy/strncat/strncmp