平地起C楼—第七层《详解字符函数和字符串函数》

在这里插入图片描述

🚩前言

在这里插入图片描述

欢迎来到C语言字符串章节,这一层主要讲解C语言中常用的字符串函数以及字符函数。通过对库函数的了解,以及对不同库函数的模拟,来熟悉C语言中的字符和字符串的操作。接下来就来讲讲它吧!👉。


🎄字符分类函数

字符分类函数:也就是用来判断单个字符是属于什么类型的,在使用C语言提供的分类字符需要包含头文件#include<ctype.h>;主要包括一下函数:

函数名作用,符合一下条件就返回真
iscntrl检测任何控制字符
isspace检测空格字符:‘ ’,换页字符:‘\f’,换行字符:‘\n’,回车字符:‘\r’,制表符:‘\t’,垂直制表符:‘\v’
isdigit判断十进制数字:‘0’~‘9’字符
isxdigit检测十六进制数字,包括十进制字符和大小写字母
islower检测小写字母‘a’~‘z’
isupper检测大写字母‘A’~‘Z’
isalpha检测字母’a’~ ‘z’ 或 ‘A’~‘Z’
islnum检测字母或者数字
ispunct检测标点,任何不属于数字或者字母的圆形字符
isgraph检测任何图形字符
isprint检测任何可打印字符,包括圆形字符和空白字符

上面例举的函数用法差不多,我拿几个来写一下代码:


islower();库函数,检测是否为小写字母:

#include<stdio.h>
#include<ctype.h>
int main()
{
    char ch1='A';
    char ch2='c';
    char ch3='m';
    //为真返回大于0的数字,为假就返回0.
    printf("%d\n",islower(ch1));
    printf("%d\n",islower(ch2));
    printf("%d\n",islower(ch2));
    printf("%d\n",islower(ch3));
    return 0;
}
  • 结果展示:
    在这里插入图片描述

isalpha();检测字母

#include<stdio.h>
#include<ctype.h>
int main()
{
    char ch1='A';
    char ch2='c';
    char ch3='m';
    char ch4='5';
    //为真返回大于0的数字,为假就返回0.
    printf("%d\n",islower(ch1));
    printf("%d\n",islower(ch2));
    printf("%d\n",islower(ch3));
    printf("%d\n",isalpha(ch4));

    return 0;
}
  • 结果展示:

在这里插入图片描述


🎄字符转换函数

在C语言中,提供了2个转换字符函数
1、int tolower(char ch);//大写转小写
2、int toepper(char ch);//小写转大写

  • 代码演示:
//字符转换函数
#include<stdio.h>
#include<ctype.h>
int main()
{
    char arr[]="Hello WORD!";
    // printf("%s\n",tolower(arr));//只能一个一个转
    int i=0;
    char ch;
    while(arr[i])
    {
        ch=arr[i];
        if(islower(ch))//是小写
        {
            ch=toupper(ch);//小写转为大写
            
        }
        putchar(ch);
        i++;
    }

    return 0;
}
  • 结果展示:

在这里插入图片描述


🎄字符串库函数

  • 字符串函数常见的有以下,都需要包含头文件#include<string.h>;👇👇👇👇
函数名功能
strlen求字符串长度,检测到’\0’就停止。返回值为无符号size_t
strcpy字符串拷贝函数。
strcat字符串追加函数。
strcmp字符串比较大小,⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。
strncpy可以限制拷贝多少个字符进来。
strncat可以限制追加个数。
strncmp限制比较字符个数。
strstr字符串查找,看原字符串中是否有字串。
strtok切分字符串。
strerror可以把参数部分错误码对应的错误信息的字符串地址返回来。

接下来依次讲一下每个函数的使用和模拟:


✍strlen()函数的使用和模拟

size_t strlen ( const char * str );
字符串中以\0结尾,返回的是字符串中\0前面的字符个数【不包含\0字符】。其返回值类型为size_t无符号整型。下面看一看它的使用:

//3、strlen()函数的使用
#include<stdio.h>
#include<string.h>
int main()
{
    char str[]="Hello Code!";
    printf("长度为:%d\n",strlen(str));
    return 0;
}

结果展示:
在这里插入图片描述


strlen()函数的3种模拟实现方法

①. 计数器实现my_strlen():

//my_strlen()模拟实现
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* str)
{
    assert(str);
    int count=0;
    while(*str++)//只要没到达'\0'就循环++
    {
        count++;
    }
    return count;
}
int main()
{
    char arr1[]="abcdefghijk";
    printf("arr1的长度:%d\n",my_strlen(arr1));
    return 0;
}
  • 结果展示:
    在这里插入图片描述

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


②. 指针运算实现my_strlen():

//2、指针运算实现
#include<stdio.h>
#include<assert.h>
int my_strlen(char* s1)
{
    assert(s1);
    char* p= s1;//先把首地址存起来
    while(*s1!='\0')
        s1++;
    return s1-p;//指针-指针得之间的元素个数。
}
int main()
{
    char arr2[]="Hello !";
    printf("arr2长度:%d\n",my_strlen(arr2));
    return 0;
}
  • 结果展示:
    在这里插入图片描述

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


③. 函数递归运算实现my_strlen(),不创建临时变量:

//3、函数递归实现
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* ptr)
{
    assert(ptr);
    if(*ptr=='\0')
        return 0;
    return 1+my_strlen(ptr+1);//至少有1个字符
}

int main()
{
    char arr3[]="abcdefgh";
    printf("arr3长度:%d\n",my_strlen(arr3));
    return 0;
}

结果展示:
在这里插入图片描述


✍strcpy()函数的使用和模拟

char* strcpy(char * destination, const char * source );

//自己模拟实现my_strcpy()
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* s1,const char* s2)
{
    assert(s2&&s1);
    char* ss1=s1;
    while(*s1++=*s2++)//拷贝到'\0'后就跳出循环
    {
        ;
    }
    return ss1;

    //优化为上面的代码
    // while(*s2)
    // {
    //     *s1=*s2;
    //     s2++;
    //     s1++;
    // }
    // *s1=*s2;//把'\0'加在最后
    // return ss1;
}

int main()
{
    char arr1[]="#####";
    char arr2[]="Hello code!";
    my_strcpy(arr1,arr2);
    printf("%s\n",arr1);
    return 0;
}

  • 结果展示:
    在这里插入图片描述

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


✍strcat()函数的使用和模拟实现

//6、strcat()函数的使用
#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[]="Hello ";
    char arr2[]="Word!";
    printf("%s\n",strcat(arr1,arr2));//arr2的内容追加到arr1里面
    return 0;
}
  • 结果展示:
    在这里插入图片描述

模拟实现my_strcat()

//strcat()函数的模拟实现
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* s1,const char* s2)
{
    //先断言处理
    assert(s1&&s2);
    //先把追加目的地的字符串的首地址存起来
    char* ss1=s1;
    //首先找到要追加到的那个字符串的'\0'
    while(*s1!='\0')//找到'\0'的地址
    {
        s1++;//此处++不能放到括号里面,不然找到的就是'\0'后面的地址,到最后打印就只是s1的内容
    }
    //然后在后面追加
    while(*s1++=*s2++);//空语句
    return ss1; 
}

int main()
{
    char arr1[]="行以之实,";
    char arr2[]="持以之久。";
    printf("%s\n",my_strcat(arr1,arr2));//arr2追加到arr1
    return 0;
}

在这里插入图片描述

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


✍strcmp()函数的使用和模拟实现

//8、strcmp()函数的使用
#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[]="abcdef";
    char arr2[]="abdcef";
    printf("%d\n",strcmp(arr1,arr2));//arr1的c 和对应arr2的d 相比,c < d(ASCII码值)

    char arr3[]="abcdef";
    char arr4[]="abcdef";
    printf("%d\n",strcmp(arr3,arr4));

    char arr5[]="abdcef";
    char arr6[]="abcdef";
    printf("%d\n",strcmp(arr5,arr6));
    return 0;
}

结果展示:
在这里插入图片描述

模拟实现my_strcmp()

//模拟实现my_strcmp()函数
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* s1,const char* s2)
{
    assert(s1&&s2);
    while(*s1==*s2)//没到'\0'就循环
    {
        //判断其中一个为'\0'就说明这两个相同
        if(*s1=='\0')
            return 0;
        s1++;
        s2++;
    }
    if(*s1>*s2)
        return 1;
    else
        return -1;
    
}

int main()
{
    char arr1[]="abcd";
    char arr2[]="abce";
    printf("%d\n",my_strcmp(arr1,arr2));

    char arr3[]="abcd";
    char arr4[]="abcd";
    printf("%d\n",my_strcmp(arr3,arr4));

    char arr5[]="abce";
    char arr6[]="abcd";
    printf("%d\n",my_strcmp(arr5,arr6));
    return 0;
}
  • 结果展示:
    在这里插入图片描述

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


✍strstr()函数的使用和模拟实现

char * strstr ( const char * str1, const char * str2);
strstr()函数作为字符串查找函数,规则就是:函数返回字符串str2在字符串str1中第⼀次出现的位置。并且字符串的⽐较匹配不包含 \0 字符,以 \0 作为结束标志。
先看一下该函数的使用:

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[]="Hello Word!";
    char arr2[]="llo";
    char arr3[]="o";
    printf("%s\n",strstr(arr1,arr2));
    printf("%s\n",strstr(arr1,arr3));//返回第一次遇到的地址
    return 0;
}
  • 结果展示:可以看到如果有多个相同的字符,则返回第一次碰到的字符位置,打印出来,直到'\0'结束。
    在这里插入图片描述

模拟实现my_strstr()函数

//模拟实现my_strstr()函数
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1,const char* str2)
{
    //检测是否有效
    assert(str1&&str2); 
    if(*str2=='\0')
    {
        return (char*)str1;
    }
    //为了不让返回字符串的arr1的首地址变化,就先用指针存起来。
    const  char* s1=NULL;
    const  char* s2=NULL;
    const  char* cur=str1;//记录从哪个位置和str2中第一个字符匹配成功的地址
    //然后从str1中开始遍历比较
    while(*cur) 
    {
        s1=cur;
        s2=str2;
        //在字符串中有相同的字符,所以我们在找到和str2中第一个字符相匹配的时候就把这个地址存起来。
        while(*s1!='\0'&&*s2!='\0'&&*s1==*s2)
        {
            s1++;
            s2++;
        }
        //在这如果str2为\0就说明比较完了,找到了即返回str1中和str2中第一个字符匹配的地址
        if(*s2=='\0')
        {
            return (char*)cur;
        }
        //调整往后移
        cur++;
    }
    return NULL;//没找到
}

int main()
{
    char arr1[]="Hello Word!";
    char arr2[]="llo";
    char* ret=my_strstr(arr1,arr2);
    if(ret==NULL)
    {
         printf("没找到啊!\n");
    }
    else
    {
         printf("%s\n",ret);
    }
     return 0;
}
  • 结果展示:
    在这里插入图片描述

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


🐬strncpy()函数的使用

strncpy()strcpy()的唯一区别就是是否规定拷贝个数。
strncpy()中拷⻉num个字符从源字符串到⽬标空间。如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个。

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

strncpy() 和 strncat() 和 strncmp() 函数代码演示

#include<stdio.h>
#include<string.h>
int main()
{
    //strncpy()函数
    char arr1[50]={0};
    char arr2[]="hello word!";
    printf("%s\n",strncpy(arr1,arr2,5));

    //strncat()函数
    char arr3[]="Hello ";
    char arr4[]="code! worde!";
    printf("%s\n",strncat(arr3,arr4,5));

    //strncmp()函数
    char arr5[]="abcdefg";
    char arr6[]="abcghij";
    printf("%d\n",strncmp(arr5,arr6,3));
    printf("%d\n",strncmp(arr5,arr6,4));


    return 0;
}



  • 结果展示:
    在这里插入图片描述

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值