C语言—字符串函数

目录

​​​​​前言

(一)长度不受限的字符串函数

1.strlen

2.strcpy

3.strcat

4.strcmp

(二)长度受限制的字符串函数

1.strncpy

2.strncat

3.strncmp

(三)字符串查找函数

1.strstr

2.strtok

(四)错误信息报告

strerror

(五)字符分类函数(选看)

1.判断字符函数

2.部分字符转换函数

​​​​​前言

C语言本身是没有字符串类型的,字符串通常放在字符数组或常量字符串中。本篇文章带大家看看C语言中对字符串处理的字符串函数。
本文所提出的函数均包含在string.h头文件中

(一)长度不受限的字符串函数

1.strlen

size_t strlen ( const char * str );

功能:获取一个字符串的长度
strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
实现方式:通过传字符串首元素地址遍历字符串,遇到’\0’停止,指针每走一次,加加一次
使用示例:

请添加图片描述
复现思路:我们根据官方的参数列表写

返回值为size_t,是无符号的
size_t strlen ( const char * str );

计数器法:
我们可以创建一个计数器,用while循环遍历字符串,指针每走一次,计数器加一,直到遇到’\0’,循环结束,返回计数器数值。

​
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<string.h>
//创建my_strlen函数
int my_strlen(const char* str)
{
    //断言,不传空指针
    assert(str);
    //创建计数器
    int count = 0;
    while (*str)
    {
        count++;
        str++;
    }
    return count;
}
//测试
int main()
{
    char arr[10] = "12345";
    printf("%u\n", my_strlen(arr));
    return 0;
}

​

指针减指针:
我们也可以设计一个头指针,用另一个指针遍历,最后两个指针相减得到的是指针间的元素个数

​
int my_strlen(char* s)
{
    //断言,不传空指针
    assert(s);
    //创建一个头指针
    char* p = s;
    //用p指针遍历字符串
    while (*p)
        p++;
    return p - s;
}
//测试
int main()
{
    char arr[10] = "12345";
    printf("%u\n", my_strlen(arr));
    return 0;
}

​

2.strcpy

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

功能:将源指针指向的字符串的所有内容拷贝到目标指针指向的空间(包括’\0’) 。
实现方式:传入目标空间和源字符串的首地址,将源字符串内容依次拷贝目标空间中,最后返回目标空间首地址。

注意事项:

  • 源字符串必须以 ‘\0’ 结束。
  • 目标空间必须足够大,以确保能存放源字符串。
  • 目标空间必须可变。

使用示例:
请添加图片描述

复现思路:我们根据官方的参数列表写

char * strcpy ( char * destination, const char * source );
目标空间必须可变所以不能用const修饰,但我们不修改源字符串,为了防止源字符串被修改,加上const修饰

遍历源字符串,把源字符串的内容赋给目标空间,一直到把’\0’也赋给目标空间,最后返回修改后的字符串首地址。

char* my_strcpy(char* dest, char* src)
{
	//先记录目标空间首地址,因为最后dest并不在首元素地址处
    char* ret = dest;
    //断言,不传空指针
    assert(dest && src);
    //*dest++的值为*dest,循环一次结束后dest加1
    //src遇到'\0'后赋值'\0'地址给dest,使*dest为'\0',结束循环
    while (*dest++ = *src++)
    {
        ;
    }
    return ret;
}
//测试
int main()
{
    char arr1[10] = "12345";
    char arr2[10] = "67890";
    printf("%s\n", arr1);
    printf("%s\n", my_strcpy(arr1, arr2));
    return 0;
}
​

3.strcat

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

功能:在一个字符串后追加另一个字符串内容。
实现方式:传入目标字符串和源字符串的首地址,将目标字符串遍历到’\0’,然后把源字符串内容赋到目标字符串后。

注意事项:

  • 源字符串必须以 ‘\0’ 结束。
  • 目标空间必须足够大,能容纳下源字符串的内容。
  • 目标空间必须可修改。
  • 字符串能自己给自己追加。

使用实例:
请添加图片描述
复现思路:我们根据官方的参数列表写

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

我们可以理解为strlen和strcpy函数的结合

char* my_strcat(char* dest, const char* src)
{
    char* ret = dest;
    assert(dest && src);
    while (*dest)
    {
        dest++;
    }
    while (*dest++ = *src++)
    {
        ;
    }
    return ret;
}
//测试
int main()
{
    char arr1[20] = "12345";
    char arr2[] = "67890";
    printf("%s\n", arr1);
    printf("%s\n", my_strcat(arr1, arr2));
    return 0;
}

4.strcmp

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

功能:比较两个字符串

  • 第一个字符串大于第二个字符串,则返回大于0的数字
  • 第一个字符串等于第二个字符串,则返回0
  • 第一个字符串小于第二个字符串,则返回小于0的数字

字符串比较方式:
从比较两个字符串的首元素开始,若相同则继续比较下一个,直到字符不同或遇到’\0’。(比较的是字符的ASCII码值)。
字符不同时,
比较两字符的ASCII码值,若第一对不匹配的字符在str1中的值大于str2中的值则返回负数,两个字符串内容相同则返回0,第一对不匹配的字符在str1中的值小于str2中的值则返回正数(在VS平台上前大与后就返回1,后大于前就返回-1,相同返回0,不同平台实现方式不同)。

实现方式:通过两个字符串指针对两个字符串进行遍历,依次比较。
使用示例:

请添加图片描述

复现思路:我们根据官方的参数列表写

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

对两个字符串进行遍历,依次比较

//进行比较不需要修改字符串,用const修饰
int my_strcmp(const char* str1, const char* str2)
{
	//断言,不传空指针
	assert(str1 && str2);
	//当字符不同时结束循环
	while (*str1 == *str2)
	{
	//进入该循环,一个字符串遍历到了'\0',则说明两个字符串已经比较到最后了,两个字符串相等
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	return (*str1 - *str2);
}
//测试
int main()
{
    char arr1[20] = "aaa";
    char arr2[] = "aap";
    int ret = my_strcmp(arr1, arr2);
    if (ret > 0)
    {
        printf("str1大于str2\n");
    }
    else if (ret < 0)
    {
        printf("str1小于str2\n");
    }
    else
    {
        printf("str1等于str2\n");
    }
    return 0;
}

(二)长度受限制的字符串函数

1.strncpy

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

功能:从源字符串拷贝num个字符到目标空间。
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
使用示例:

请添加图片描述
复现思路:与strcpy函数一样,只是多了一个参数num,指复制num个字符(包括’\0’)
代码:

char* my_strncpy(char* dest, const char* src, size_t num)
{
    char* ret = dest;
    assert(dest && src);
    for (int i = 0; i < num; i++)
    {
        *dest++ = *src++;
    }
    return ret;
}
int main()
{
    char arr1[14] = "xxxxxxxxx";
    char arr2[] = "1234";
    printf("%s\n", my_strncpy(arr1, arr2, 6));
    return 0;
}

2.strncat

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

功能:与strcat一样,只是多了一个参数num,指追加num个源字符串内容到目标字符串中。
若源字符串长度小于num,则仅复制’\0’之前的内容。
使用实例:

请添加图片描述

复现思路代码:

char* my_strncat(char* dest, const char* src, size_t num)
{
    char* ret = dest;
    assert(dest && src);
    while (*dest)
    {
        dest++;
    }
    for (int i = 0; i < num; i++)
    {
        *dest++ = *src++;
    }
    return ret;
}
//测试
int main()
{
    char arr1[13] = "hello ";
    char arr2[6] = "world";
    printf("%s\n", my_strncat(arr1, arr2, 5));
    return 0;
}

3.strncmp

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

功能:与strcmp一样,只是多了一个参数num,指比较num个。
使用示例:

请添加图片描述
请添加图片描述
复现代码:

int my_strncmp(const char* str1, const char* str2, size_t num)
{
    assert(str1 && str2);
    for (int i = 0; i < num; i++)
    {
        if (*str1 != *str2)
            return (*str1 - *str2);
        str1++;
        str2++;
    }
    return 0;
}
//测试
int main()
{
    char arr1[20] = "aaa";
    char arr2[] = "aap";
    int ret = my_strncmp(arr1, arr2, 3);
    if (ret > 0)
    {
        printf("str1大于str2\n");
    }
    else if (ret < 0)
    {
        printf("str1小于str2\n");
    }
    else
    {
        printf("str1等于str2\n");
    }
    return 0;
}

(三)字符串查找函数

1.strstr

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

功能:在str1字符串中找str2(待查找的字符串)字符串。
    即查找子字符串

实现思路:
1.先从头遍历str1,若找到了与str2首字符相同的字符,则创建一个指针cp用来记录这个位置,再从这个位置向后开始依次比较。
2.创建s1,s2两个指针,用来遍历比较,若s1一直等于s2,s2能一直走直到找到’\0’,则说明在str1找到了str2这个字符串,返回第一个相同字符的地址(cp),否则就返回NULL。
3.若遍历比较中有不同,则s1,s2停止遍历,cp向前走一步(cp++),s1复位到此时cp的这个位置(s1=cp),s2再次复位到首地址(s2=str2),重复步骤2,直到s2找到’\0’。
使用示例:

请添加图片描述
复现代码:

char* my_strstr(const char* str1, const char* str2)
{
    char* s1 = str1;
    char* s2 = str2;
    char* cp = str1;
    //因为str1中总含有'\0'
    //故*str2 == '\0'时直接返回
    if (*str2 == '\0')
        return str1;
    while (*cp)
    {
        //复位
        s1 = cp;
        s2 = str2;
        //若两字符串指针都没有走到'\0',
        //且两字符串指针所指向的字符相等
        //则进行比较遍历
        while (s1 && s2 && *s1 == *s2)
        {
            s1++;
            s2++;
        }
        //若待查找字符串指针走到'\0',返回cp
        if (*s2 == '\0')
            return cp;

        cp++;
    }

}
int main()
{
    char arr1[20] = "helhello";
    char arr2[20] = "hello";
    char* ret = my_strstr(arr1, arr2);
    if (ret != NULL)
        printf("找到了\n");
    else
        printf("没找到\n");
    printf("%s\n", ret);
    return 0;
}

2.strtok

char * strtok ( char * str, const char * sep );

功能:用于分割字符串
实现方式:

  • sep参数是个字符串,定义了用作分隔符的字符集合
  • 第一个参数是一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
  • strtok函数找到str中的下一个标记,并将其用’0’结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改)
  • 若strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
  • 若strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
  • 如果字符串中不存在更多的标记,即全部分割完毕,则返回 NULL 指针。

使用示例:

int main()
{
    char arr[] = "Qinshangyan@qq.com";
    char sep[] = "@.";
    //strtok函数会修改字符串
    //所以用临时拷贝分割
    char copy[30] = {0};
    strcpy(copy, arr);
    char* ret = NULL;
    //除了第一次切割外,我们想要再次切割,就要在第一个参数传入NULL
    //即告诉函数我们要继续切割
    //如果全部分割完毕,函数会返回一个空指针,否则就返回一个指向这个标记的指针
    for (ret = strtok(copy, sep); ret != NULL; ret = strtok(NULL, sep))
    {
        printf("%s\n", ret);
    }
    return 0;
}

(四)错误信息报告

strerror

功能:返回错误码,所对应的错误信息。
错误码:库函数在执行时发生错误,会将一个错误码存放到errno这个变量中(int 类型,声明在头文件errno.h中,errno是C语言提供的一个全局变量)

使用示例:
请添加图片描述
部分错误码对应的错误信息:
请添加图片描述

(五)字符分类函数(选看)

1.判断字符函数

函数如果其参数符合下列条件就返回真
isdigit十进制数字 0~9
isxdigit十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A ~F
islower小写字母a~z
isupper大写字母A~Z
isalpha字母a~z或A ~Z
isalnum字母或者数字,a~z,A ~Z,0 ~9
ispunct标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph任何图形字符
isprint任何可打印字符,包括图形字符和空白字符
iscntr任何控制字符
isspace空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’

2.部分字符转换函数

int tolower ( int c );转换成小写
int toupper ( int c );转换成大写

使用示例:
请添加图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值