--size_t strlen(const char *str)
头文件 string.h
字符串以’\0’作为结束标志,strlen函数返回的是字符串中’\0’以前,字符的个数(不包含’\0’)
参数指向的字符串必须要以’\0’为结束标志。
注意函数的返回值为size_t 和unsigned int 一个意思,为无符号数 (再怎莫说一个字符串中字符的个数怎么也不能为负数吧!)
图文解释
:
代码演示
#include
#include
//取字符串长度
int main()
{
char arr[10] = "bit";
int ret = strlen(arr);
printf("ret = %d", ret);
return 0;
}
实现方法:
计数器法
指针-指针法
函数递归法
#include
//模拟实现strlen函数
//方法一:计数器法
//方法二:指针-指针法
//方法三:(不使用临时变量)递归法
int my_strlen1(char* arr)
{
int count = 0;
while (*arr != '\0')
{
count++;
arr++;
}
return count;
}
int my_strlen2(char* arr)
{
char* dest = arr; //记录字符串的首地址
while (*arr != '\0')
{
arr++;
}
//arr记录字符串的末尾地址
return arr - dest;//两个地址相减得到的是他们之间的元素个数
}
int my_strlen3(char* arr)
{
if (*arr != '\0')
{
return 1 + my_strlen3(arr + 1);
}
else
{
return 0;
}
}
int main()
{
char arr[10] = "bit";
int ret1 = my_strlen1(arr);
int ret2 = my_strlen2(arr);
int ret3 = my_strlen3(arr);
printf("ret = %d\n", ret1);//计数器法
printf("ret = %d\n", ret2);//指针-指针法
printf("ret = %d\n", ret3);//函数递归法
return 0;
}
char * strcpy(char *destination,const char*sourse)
返回类型 char* 返回拷贝之后字符串的首字符的地址
头文件string.h
char * destination 表示的是要拷贝的目的地字符串的地址
const char *sourse 代表的是源字符串的地址,这里源代码使用const修饰,因为把他设为不可更改的,这样保证了代码的健壮性。
重点
源字符串必须以’\0’结尾
目标空间必须足够大,以保证能有效的存放下源字符串
目标空间必须是可以更改的
图文解释
:
代码演示
#includ <stdio.h>
#include
int main()
{
char arr1[10] = "hello world";
char arr2[10] = "bit";
printf("%s",strcpy(arr1,arr2));//将arr2中的内容拷贝到arr1中
return 0;
}
代码演示
//模拟实现strcpy函数
#include
#include
//简单实现
void my_strcpy(char* arr1, const char* arr2)
{
assert(arr1 != NULL && arr2 != NULL); //保证arr1和arr2传过来的不是空地址
char* arr = arr1; //记录arr1地址
while (*arr1++ = *arr2++)
{
;
}
printf("%s", arr);
}
//一般实现
void my_strcpy1(char* arr1, const char* arr2)
{
assert(arr1 != NULL && arr2 != NULL);
char* arr = arr1;
while (*arr2 != '\0')
{
*arr1 = *arr2;
arr1++;
arr2++;
}
printf("%s\n", arr);
}
int main()
{
char arr1[10] = "bitres";
char arr2[5] = "tea";
my_strcpy(arr1, arr2);
// my_strcpy1(arr1, arr2);
return 0;
}
char * strcat(char*destination,const char *score )
头文件:string.h
char * destination 目标字符串的首地址
const char* source 将要追加到目标字符串后的源字符串的首地址,用const修饰为不可更改的源字符串,让这个函数更加安全,使代码更为健壮
重点
源字符串必须以’\0’结尾
目标空间必须可更改
目标空间必须足够大,以确保能放下源字符串和目标字符串。
图文解释
代码演示
#include
#include
int main()
{
char arr1[10] = "bit";
char arr2[10] = "tea";
printf("%s", strcat(arr1, arr2)); //追加arr2
return 0;
}
代码演示
#include
#include
void my_strcat(char* arr1, const char* arr2)
{
assert(arr1 && arr2);
char* dest = arr1;
//先找到第一个字符串的结束标志'\0'
while (*arr1 != '\0')
{
arr1++;
}
//找到第一个字符串的末尾
while (*arr1++ = *arr2++) //依次追加源字符串的每个字符
{
;
}
printf("%s", dest);
}
int main()
{
char arr1[20] = "bit";
char arr2[20] = "abc";
my_strcat(arr1, arr2);
return 0;
}
既然字符串可以追加,那么字符串可以追加自己吗?
答案是不能的,因为在字符串追加的过程中字符串的结束标志’\0’会被字符覆盖,从而一直追加
图文解释
int strcmp (const char *str1,const char*str2)
头文件:string.h
char*str1 和 char *str2 都是两个将要进行比较的两个字符串的首地址。
用const 修饰 保证它的安全性
标椎规定:第一个字符串大于第二个字符串,则返回大于0的数
第一个字符串小于第二个字符串,则返回小于0的数
第一个字符串等于第二个字符串,则返回0
图文解释:
代码演示
#include
#include
int main()
{
char arr1[] = "bitse";
char arr2[] = "bit";
int ret = strcmp(arr1, arr2);
if (ret > 0)
{
printf(">\n");
}
else if ( ret < 0)
{
printf("<\n");
}
else
{
printf("=\n");
}
return 0;
}
代码演示
#include
#include
int my_strcmp(const char* arr1, const char* arr2)
{
assert(arr1 != NULL && arr2 != NULL);
//一个字符一个字符比较
while (*arr1++ == *arr2++) //如果两个字符相等,向后依次遍历
{
if (*arr1 == '\0') //如果两个字符串,中的字符一直相等,直到比到第一个字符串的末尾'\0',就返回0
{
return 0;
}
}
if (*arr1 > *arr2) //如果比到不相同的一位,进行比较。第一个字符串>第二个字符串
{
return 1;
}
else //第一个字符串<第二个字符串
{
return -1;
}
}
int main()
{
char arr1[] = "abcd";
char arr2[] = "abc";
int ret = my_strcmp(arr1, arr2);
if (ret > 0)
{
printf(">\n");
}
else if (ret < 0)
{
printf("<\n");
}
else
{
printf("=\n");
}
return 0;
}
char * strncpy ( char * destination, const char * source, size_t num
头文件:string.h
char * destination:表示目标字符串的首地址
char * source:表示源字符串的首地址
size_t:表示源字符串的字符添加到目标字符串中的个数
strncpy 函数功能:规定原字符串中的字符添加到目标字符串中的个数。
代码演示
#include
#include
int main()
{
char arr1[20] = "abcde";
char arr2[20] = "***********";
strncpy(arr2,arr1,1);
printf("%s",arr2);
return 0;
}
#include
#include
char* my_strncpy(char* dest, const char* src, size_t count)
{
assert(dest != NULL);
assert(src != NULL);
char* start = dest;
//当限制的拷贝数字不为0时,源字符串中的字符一个一个的被拷贝到目标字符串中
while (count && (*dest++ = *src++) != '\0')
{
count--;
}
//当传进的数字为0时,直接打印没有被拷贝的目标字符串
if (count == 0)
{
while (count--)
{
*dest++ = '\0';
}
}
return start;
}
int main()
{
char arr1[10] = "abcdef";
char arr2[10] = "eeeeee";
size_t num = 0;
scanf("%d", &num);
printf("%s", my_strncpy(arr1, arr2, num));
return 0;
}
char * strncat ( char * destination, const char * source, size_t num)
头文件:string.h
char * destionation 表示目标字符串首地址
char * source 表示源字符串的首地址
size_t num 表示的是追加到目标字符串中源字符串中字符的个数。
注意:目标字符串必须要自够长,足以容纳下目标字符串和追加过去的字符串的长度,否则会溢出。
strncat的使用
#include
#include
int main()
{
char arr1[20] = "********";
char arr2[20] = "bit";
size_t num = 0;
scanf("%d", &num);
printf("%s", strncat(arr1, arr2, num));
return 0;
}
#include
char* my_strncat(char* arr1, char* arr2, size_t num)
{
char* arr = arr1;
//第一步:先找到第一个字符的'\0'
while (*arr1 != '\0')
{
arr1++;
}
//然后在追加字符
while (num--)
{
*arr1 = *arr2;
arr1++;
arr2++;
}
return arr;
}
int main()
{
char arr1[10] = "abcde";
char arr2[10] = "bit";
size_t num = 0;
scanf("%d", &num);
printf("%s", my_strncat(arr1, arr2, num));
return 0;
}
int strncmp ( const char * str1, const char * str2, size_t num )
头文件:string.h
const char * str1 表示第一个比较的字符串;
const char * str2 表示第二个比较的字符串;
size_t num 表示要比较字符的个数;
strncmp的使用
#include
#include
int main()
{
char arr1[20] = "abcd";
char arr2[20] = "abde";
int num = 0;
scanf("%d", &num);
int ret = strncmp(arr1, arr2, num);
if (ret > 0)
{
printf("arr1 > arr2");
}
else if(ret < 0)
{
printf("arr1 < arr2");
}
else
{
printf("arr1 = arr2");
}
return 0;
}
strncmp函数不同于strcmp函数,因为strncmp函数可以规定比较字符的个数,较为安全。
当第一个字符串 > 第二个字符串 返回1
当第一个字符串 = 第二个字符串 返回0
当第一个字符串 < 第二个字符串 返回-1
strncmp的底层实现
int __cdecl strncmp
(
const char *first,
const char *last,
size_t count
)
{
size_t x = 0;
if (!count)
{
return 0;
}
/*
* This explicit guard needed to deal correctly with boundary
* cases: strings shorter than 4 bytes and strings longer than
* UINT_MAX-4 bytes .
*/
if( count >= 4 )
{
/* unroll by four */
for (; x < count-4; x+=4)
{
first+=4;
last +=4;
if (*(first-4) == 0 || *(first-4) != *(last-4))
{
return(*(unsigned char *)(first-4) - *(unsigned char *)(last-4));
}
if (*(first-3) == 0 || *(first-3) != *(last-3))
{
return(*(unsigned char *)(first-3) - *(unsigned char *)(last-3));
}
if (*(first-2) == 0 || *(first-2) != *(last-2))
{
return(*(unsigned char *)(first-2) - *(unsigned char *)(last-2));
}
if (*(first-1) == 0 || *(first-1) != *(last-1))
{
return(*(unsigned char *)(first-1) - *(unsigned char *)(last-1));
}
}
}
/* residual loop */
for (; x < count; x++)
{
if (*first == 0 || *first != *last)
{
return(*(unsigned char *)first - *(unsigned char *)last);
}
first+=1;
last+=1;
}
return 0;
}
const char * strstr ( const char * str1, const char * str2 );
函数功能:在一个字符串中,看是否能找到第二个字符串,也就是在一个字符串中寻找子串。
头文件:string.h
const char * str1 表示的是字符串主串
const char * str2 表示的是字符串子串
返回值:
当在第一个字符串中找到了第二个字符串,就返回在第一个字符串中找到第一个字符串的首地址
如果在第一个字符串中找不到第二个字符串,就返回一个空指针(null).
strstr 函数的使用
代码实现
#include
#include
int main()
{
char arr1[10] = "abcdef";
char arr2[10] = "abc";
char * ret = strstr(arr1, arr2);
if (ret == NULL)
{
printf("找不到\n");
}
else
{
printf("找到了\n");
}
return 0;
}
#include
#include
char* my_strstr(const char* arr1, const char* arr2)
{
//保证传过来的字符串不为空
assert(arr1 && arr2);
//设置两个,相互比较的字符串
const char* s1 = arr1;
const char* s2 = arr2;
//设置一个有记忆了的指针
const char* cp =arr1;
//函数功能
while (*cp)
{
s1 = cp;
s2 = arr2;
//比较
while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return (char*)cp;
}
cp++;
}
return NULL;
}
int main()
{
char arr1[10] = "aabcef";
char arr2[10] = "abc";
char* ret = my_strstr(arr1, arr2);
if (ret == NULL)
{
printf("没找到\n");
}
else
{
printf("找到了\n");
}
return 0;
}