C语言进阶笔记(字符函数和字符串函数1)


文章目录

求字符串长度函数

strlen

--size_t strlen(const char *str)

头文件 string.h
字符串以’\0’作为结束标志,strlen函数返回的是字符串中’\0’以前,字符的个数(不包含’\0’)
参数指向的字符串必须要以’\0’为结束标志。
注意函数的返回值为size_t 和unsigned int 一个意思,为无符号数 (再怎莫说一个字符串中字符的个数怎么也不能为负数吧!)
图文解释
在这里插入图片描述

使用strlen函数

代码演示

#include <stdio.h>
#include <string.h>
//取字符串长度
int main()
{
	char arr[10] = "bit";
	int ret = strlen(arr);
	printf("ret = %d", ret);
	return 0;
}
  • 运行结果:3

模拟实现strlen函数

实现方法:
计数器法
指针-指针法
函数递归法

#include <stdio.h>
//模拟实现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;
}
 

在这里插入图片描述

字符长度不受限字符串函数

strcpy(字符串拷贝函数)

char * strcpy(char *destination,const char*sourse)

返回类型 char* 返回拷贝之后字符串的首字符的地址
头文件string.h
char * destination 表示的是要拷贝的目的地字符串的地址
const char *sourse 代表的是源字符串的地址,这里源代码使用const修饰,因为把他设为不可更改的,这样保证了代码的健壮性。
重点
源字符串必须以’\0’结尾
目标空间必须足够大,以保证能有效的存放下源字符串
目标空间必须是可以更改的
图文解释
在这里插入图片描述

使用strcpy函数

代码演示

 #includ <stdio.h>
 #include <string.h>
 int main()
 {
   char arr1[10] = "hello world";
   char arr2[10] = "bit";
   printf("%s",strcpy(arr1,arr2));//将arr2中的内容拷贝到arr1中
   return 0;
 }
模拟实现strcpy函数

代码演示

 //模拟实现strcpy函数
#include <stdio.h>
#include <assert.h>
//简单实现
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;
}

在这里插入图片描述
在这里插入图片描述

  • 运行结果:tea

strcat(字符串追加函数)

char * strcat(char*destination,const char *score )

头文件:string.h
char * destination 目标字符串的首地址
const char* source 将要追加到目标字符串后的源字符串的首地址,用const修饰为不可更改的源字符串,让这个函数更加安全,使代码更为健壮
重点
源字符串必须以’\0’结尾
目标空间必须可更改
目标空间必须足够大,以确保能放下源字符串和目标字符串。
图文解释
在这里插入图片描述

使用strcat函数

代码演示

 #include <stdio.h>
 #include <string.h>
int main()
{
	char arr1[10] = "bit";
	char arr2[10] = "tea";
	printf("%s", strcat(arr1, arr2)); //追加arr2
	return 0;
}
  • 运行结果:bittea
模拟实现strcat函数

代码演示

 #include <stdio.h>
#include <assert.h>
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;
}
  • 运行结果:bitabc
    在这里插入图片描述
    在这里插入图片描述

既然字符串可以追加,那么字符串可以追加自己吗?
答案是不能的,因为在字符串追加的过程中字符串的结束标志’\0’会被字符覆盖,从而一直追加
图文解释
在这里插入图片描述

strcmp(字符串比较函数)

int strcmp (const char *str1,const char*str2)

头文件:string.h
char*str1 和 char *str2 都是两个将要进行比较的两个字符串的首地址。
用const 修饰 保证它的安全性
在这里插入图片描述
标椎规定:第一个字符串大于第二个字符串,则返回大于0的数
第一个字符串小于第二个字符串,则返回小于0的数
第一个字符串等于第二个字符串,则返回0
图文解释:
在这里插入图片描述

使用strcmp函数

代码演示

 #include <stdio.h>
 #include <string.h>
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;
}
模拟实现strcmp函数

代码演示

 #include <stdio.h>
 #include <assert.h>
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;
}

长度受限的字符串函数介绍

strncpy

char * strncpy ( char * destination, const char * source, size_t num

头文件:string.h
char * destination:表示目标字符串的首地址
char * source:表示源字符串的首地址
size_t:表示源字符串的字符添加到目标字符串中的个数
strncpy 函数功能:规定原字符串中的字符添加到目标字符串中的个数。

代码演示

 #include <stdio.h>
 #include <string.h>
 int main()
 {
   char arr1[20] = "abcde";
   char arr2[20] = "***********";
   strncpy(arr2,arr1,1);
   printf("%s",arr2);
  return 0;
}

运行结果:
在这里插入图片描述
模拟实现strncpy函数
代码演示:

 #include <stdio.h>
 #include <assert.h>
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;
}

图文解释
在这里插入图片描述
在这里插入图片描述

strncat

char * strncat ( char * destination, const char * source, size_t num)

头文件:string.h
char * destionation 表示目标字符串首地址
char * source 表示源字符串的首地址
size_t num 表示的是追加到目标字符串中源字符串中字符的个数。
注意:目标字符串必须要自够长,足以容纳下目标字符串和追加过去的字符串的长度,否则会溢出。

strncat的使用

 #include <stdio.h>
#include <string.h>
int main()
{
    char arr1[20] = "********";
    char arr2[20] = "bit";
    size_t num = 0;
    scanf("%d", &num);
    printf("%s", strncat(arr1, arr2, num));
    return 0;
}

运行结果:
在这里插入图片描述
模拟实现strncat函数
代码演示:

 #include<stdio.h>
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;
}

图文解释
在这里插入图片描述
在这里插入图片描述

strncmp

int strncmp ( const char * str1, const char * str2, size_t num )

头文件:string.h
const char * str1 表示第一个比较的字符串;
const char * str2 表示第二个比较的字符串;
size_t num 表示要比较字符的个数;

strncmp的使用

 #include <stdio.h>
 #include <string.h>
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;
}

图文解释
在这里插入图片描述

字符串查找

strstr函数的使用

const char * strstr ( const char * str1, const char * str2 );

函数功能:在一个字符串中,看是否能找到第二个字符串,也就是在一个字符串中寻找子串。
头文件:string.h
const char * str1 表示的是字符串主串
const char * str2 表示的是字符串子串
返回值:
在这里插入图片描述
当在第一个字符串中找到了第二个字符串,就返回在第一个字符串中找到第一个字符串的首地址
如果在第一个字符串中找不到第二个字符串,就返回一个空指针(null).

strstr 函数的使用
代码实现

 #include <stdio.h>
 #include <string.h>
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;
}

运行结果:
在这里插入图片描述

strstr函数的模拟实现

 #include <stdio.h>
#include <assert.h>
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;
}

图文解释:
在这里插入图片描述

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小周学编程~~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值