【C语言进阶】字符串处理函数的介绍

目录

前言:

一、字符串处理函数介绍:

1.strlen函数:

2.strcpy函数:

3.strcat函数:

4.strcmp函数:

5.strncpy函数:

6.strncat函数:

7.strncmp函数:

8.strstr函数:

9.strtok函数:

10.strerror函数:

11.memcopy函数:

12.memmove函数:

13.memcmp函数:

二、总结:


前言:

        本文我们将进入对字符串处理函数的学习,重点介绍处理字符和字符串的库函数的使用和注意事项。

一、字符串处理函数介绍:

      C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串字符数组中。其中,字符串常量是用于那些对它不修改的字符串函数。

1.strlen函数:

        相信大家对strlen函数已经不陌生,在C语言初阶我们就经常使用这个函数了。

4cd5f613ea7a4d4e94d520fdfb38d19d.png

         strlen函数(string length)的作用是用于返回字符串结束标志‘\0’之前出现的字符个数,因此,strlen函数处理的字符串对象必须是以结束标志‘\0’结尾的字符串。其返回值类型是size_t类型,也就是无符号类型。

下面是strlen函数的基本使用方法:

#include<stdio.h>
#include<string.h>

int main()
{
    char arr1[] = "hellow";
    char arr2[] = { 'h','e','l','l','o','w','\0' };
    char arr3[] = { 'h','e','l','l','o','w' };
    
    int len1 = strlen(arr1);
    int len2 = strlen(arr2);
    int len3 = strlen(arr3);

    printf("%d ", len1);
    printf("%d ", len2);
    printf("%d ", len3);

    return 0;

}

该代码输出结果如下:

43fcc7552e9e4f648d7cbdca0b27a8d1.png

        我们使用字符型数组将字符串存储起来,接着使用strlen函数计算字符串‘hellow’中所有字符的数量(使用双引号初始化字符串时,编译器自动在最后面加上‘\0’),并可以可以使用一个整形变量接收strlen函数的返回值,进行打印。当没有结束标志时候,strlen会一直读下去,这也就是len3=33的原因。

        并且我们还说到,strlen函数的返回类型为无符号数,因此strlen函数不可以直接用来比较两个字符串的大小;例如:

#include<stdio.h>
#include<string.h>

int main()
{
    char arr1[] = "hellow";
    char arr2[] = "hel";
   
    if (strlen(arr2) - strlen(arr1)>0)
    {
        printf("arr2>arr1");
    }
    else
    {
        printf("arr2<arr1");
    }
    return 0;

}

        按照我们正常思路是3-6为-3,然后会执行else语句。但实际上:

0391c1e696e94d8ba43cbd8f27b9c21c.png

         这是因为strlen函数的返回类型是无符号类型,得出的结果也是无符号类型,于是原本第一位即符号位上的数字也将被作为数据的一部分,因而实际得出的结果是一个非常大的整数,也就是大于0,也就执行了if语句。

        如果你实在要比较大小的话,这边介绍两种方式:

方式一:

//用两个变量先存起来
#include<stdio.h>
#include<string.h>

int main()
{
    char arr1[] = "hellow";
    char arr2[] = "hel";
   
    int len1 = strlen(arr1);
    int len2 = strlen(arr2);

    if (len2-len1>0)
    {
        printf("arr2>arr1");
    }
    else
    {
        printf("arr2<arr1");
    }
    return 0;

}

方式二:

#include<stdio.h>
#include<string.h>

//强制类型转换
int main()
{
    char arr1[] = "hellow";
    char arr2[] = "hel";
   
    if ((int)strlen(arr2) - (int)strlen(arr1)>0)
    {
        printf("arr2>arr1");
    }
    else
    {
        printf("arr2<arr1");
    }
    return 0;

}

2.strcpy函数:

        在之前的学习中,strcpy函数也是我们经常使用的字符串处理函数之一。

10802c2f08ca490fa1d9d4973f0a5c3a.png

        strcpy函数(string copy)的作用是:可以将字符串从源地址复制到目的地址,通俗来讲就是用来实现字符串的复制和拷贝。并且它会将源地址内的结束标志‘\0’一并拷贝过去,因此源地址必须以‘\0’一并拷贝过去,因此源地址必须以‘\0’结尾,且目的地址也将以结束标识符结尾 。而且,因为其作用拷贝字符串,因此目标地址的空间必须足够大,必须有足够大的空间容纳下源地址内字符串,同时目的地址的空间必须是可变的,可修改的。

        下面是strpy函数的基本使用方式:

#include<stdio.h>
#include<string.h>

int main()
{
    const char arr1[] = "hellow";
    const char arr2[10] = { 0 };

    printf("%s\n", arr1);
    printf("%s\n", arr2);

    //strcpy(目的地址,源地址);
    strcpy(arr2, arr1);
    
    printf("%s\n", arr1);
    printf("%s\n", arr2);
    return 0;

}

        我们初始化字符数组arr中的内容,并使arr2中内容为空。首先我们将两个字符串进行打印,验证拷贝前两字符串中的存储内容。接着我们使用strcpy函数将字符数组arr1中的字符串拷贝至arr2中,并在此之前打印两数组中的内容对拷贝结果进行验证。

        我们要特别注意的是strcpy函数返回的是目标空间的起始地址,该函数设置返回值类型的实现链式访问。(以后会讲到,这里仅做了解)。

3.strcat函数:

        这个字符串处理函数就比较陌生了,在我们之前的学习中没有用到过,,甚至见都没有见过。

5520cc4e0d4c4e68ad379ef9a59d8242.png

        strcat函数(string catenate)的作用是:将源地址的字符串追加到目的地址。与字符串拷贝函数相同,它在进行补充追加时是从目的地址的结束标识符‘\0’开始追加的,追加至源地址的结束标识符停止的。且它同样要求目标地址内的空间必须足够大,要有足够的空间容纳下源地址内字符串,同时目的地址的空间必须是可变的、可修改的。

        下面是strcat函数的基本使用方式:

#include<stdio.h>
#include<string.h>

int main()
{
    const char arr1[20] = "hellow ";
    const char arr2[20] = "world";

    printf("%s\n", arr1);
    printf("%s\n", arr2);

    //strcat(目的地址,源地址);
    strcat(arr1, arr2);
    
    printf("%s\n", arr1);
    printf("%s\n", arr2);
    return 0;

}

        我们同样首先定义并初始化两个字符数组,接着打印他们验证他们各自内部的存储内容。然后通过是用strcat函数,我们将字符数组arr2中的内容,成功的追加补充倒了字符数组arr1中,并再次进行打印,验证追加补充的结果。

        注意,strcat函数无法追加自己。原因很好理解,我们在定义是就已经固定了字符数组的储存空间了,当追加自己时,相当于将自己与自己相同大小的字符数组,即两倍自身大小的数据放入自己的储存空间,可想而知一定是不可行的。

4.strcmp函数:

        dc3a7acff043435d8e2f6c2c2cad7e71.png

        strcmp函数(string compare)的作用是:按照顺序依次比较两字符串对应位置字符的ASCII码值(注意不是比较两字符串的长度哦),直到结束标识符‘\0’或对应位置的字符不同。若比较到结束标识符都没有不同则字符串相等,若两字符串对应位置字符有不同,谁的ASCII码值小,那个ASCII码值小的字符比较小。

同样的我们来看看strcmp的基本使用方式:

#include<stdio.h>
#include<string.h>

int main()
{
    const char arr1[20] = "abc";
    const char arr2[20] = "abz";

    int ret = strcmp(arr1, arr2);
    //如果arr1大于arr2,则返回大于0的数;
    //如果arr1等于arr2,则返回等于0的数;
    //如果arr1小于arr2,则返回小于0的数;

    if (ret > 0)
    {
        printf("arr1>arr2");
    }
    else if (ret == 0)
    {
        printf("arr1=arr2");
    }
    else
    {
        printf("arr1<arr2");

    }
    
    return 0;

}

        首先我们定义并初始化两个字符数组,接着对两个数组进比较,根据strcmp函数的比较结果得到返回值,再根据返回值反馈我们想要的字符串比较结果。

        这里的要点是:该函数的作用并不是比较字符串的长短,而是比较对应位置字符ASCII码值的大小。

5.strncpy函数:

c577a3f58ff343ecbbc6c6903c37a837.png

        strncpy函数(string number copy)的作用是:将指定长度的字符串复制到字符数组中,即表示把源地址中字符串开始的前n个字符拷贝到目的地址中。与strcpy相同,它同样会将源地址内的结束标识符‘\0'一并拷贝过去,因此源地址必须以’\0‘结尾,且目的地址也将以结束标识符结尾。并且因为其作用为拷贝字符串,所以目标地址内的空间必须足够大,要有足够的空间容纳下源地址内的字符串,同时目的地址空间必须是可变,可修改的。 

下面来看strncpy函数的基本使用方式:

#include<stdio.h>
#include<string.h>

int main()
{
    const char arr1[] = "hellow";
    const char arr2[10] = { 0 };

    printf("%s\n", arr1);
    printf("%s\n", arr2);

    //strcpy(目的地址,源地址,拷贝个数);
    strncpy(arr2, arr1,3);

    printf("%s\n", arr1);
    printf("%s\n", arr2);
    return 0;

}

        我们看到,使用该函数,我们成功的将字符数组arr1中前3个字符拷贝到字符数组arr2中,并且通过前后两次打印的打印验证了按指定长度拷贝操作完成。

ps:若源字符串的长度小于我们传递过去的参数,则拷贝完源字符串之后,将在后面加字符'\0',直至拷贝够参数规定的个数。

6.strncat函数:

00178ae0104f43f1973eee9719041478.png

        strncat函数(string number catenate)的作用:从源地址处将指定长度的字符串追加到目的地址中。与strcat类似,他在进行补充追加时,也是从目的地址的结束标识符'\0'开始追加的,不同的是追加到参数限制的字符数出停止。 但它同样要求目标地址内的空间必须足够大,要有足够的空间容纳下追加的字符串,同时目的地址的空间必须是可变的、可修改的。

strncat的基本使用方式:

#include<stdio.h>
#include<string.h>

int main()
{
    const char arr1[20] = "hellow ";
    const char arr2[20] = "world";

    printf("%s\n", arr1);
    printf("%s\n", arr2);

    //strcat(目的地址,源地址,追加个数);
    strncat(arr1, arr2,3);

    printf("%s\n", arr1);
    printf("%s\n", arr2);
    return 0;

}

        首先我们定义并初始化两个字符数组,接着打印追加前他们各自的内容,然后我们使用strncat函数有限制的从数组arr1向arr2追加了3个字符,最后进行打印验证。

7.strncmp函数:

65e5bc101e6a41f4a195ec5bd4fcf7c2.png

 strncmp函数(string number compare)的作用是:有限制的按照顺序依次比较两字符串对应位置字符的ASCII码值(注意不是比较两字符串的长度哦),直到参数限制数位置上的字符都比较结束或对应位置的字符不同。若参数限制位数位置上的字符都比较结束且都没有不同则两字符串相等,若两字符串对应位置字符有不同,谁的ASCII码值小,那个ASCII码值小的字符比较小。

下面是strncmp函数的基本使用方式:

#include<stdio.h>
#include<string.h>

int main()
{
    const char arr1[20] = "abcdef";
    const char arr2[20] = "abz";

    int ret = strncmp(arr1, arr2,3);
    //如果arr1大于arr2,则返回大于0的数;
    //如果arr1等于arr2,则返回等于0的数;
    //如果arr1小于arr2,则返回小于0的数;

    if (ret > 0)
    {
        printf("arr1>arr2");
    }
    else if (ret == 0)
    {
        printf("arr1=arr2");
    }
    else
    {
        printf("arr1<arr2");

    }

    return 0;

}

        其作用原理与作用过程跟strcmp十分类似,唯一不同便是限制了比较的字符数,所以就不过多阐述了。

8.strstr函数:

      8682146a00a744c8b21f2b2dd04ec5e9.png  

strstr函数(string string)的作用是:从一个字符串中寻找其字符串,通俗来讲就是从一个字符串中寻找另外一个字符串。若找到目标字符串则返回指向目标字符串的指针,若没有找到则返回空指针 。

我们来看看strstr函数的基本使用方式:

#include<stdio.h>
#include<string.h>

int main()
{
    const char arr1[20] = "abcdef";
    const char arr2[20] = "cd";

    //从arr1中找arr2;
    char* ps = strstr(arr1, arr2);

    if (ps == NULL)
    {
        printf("没找到\n");
    }
    else
    {
        printf("找到了:%s", ps);
    }

    

    return 0;

}

        我们定义并初始化了两个字符数组,并使用strstr函数进行字符串寻找,并使用了字符型指针接收函数的返回值,最后对接受了返回值的指针ps进行判断,若为空则为没有从数组arr1找到字符串arr2,反之则会找到了。

9.strtok函数:

46be62ef885641309f35c898fe333505.png

        strtok函数(string token)的作用是:将字符串分解为一组字符串。听起来有点懵,实际很简单。该函数有两个数组作为参数,他的实际作用便是将其中一个数组组为分割数组,在另一个数组中寻找这些“分割符”,并在分隔符处将这个数组内的字符串加上结束标识符'\0',将其分割成一组(多个)字符串。若第一个参数不为NULL;将找到字符数组中的第一个标记并保存他在字符串中的位置;若第一个参数为NULL,将在同一个字符串中被保存的位置开始,查找下一个标记。如果字符串中不存在更多的标记,则返回 NULL 指针。

下面是strtok函数的基本使用方式:

#include<stdio.h>
#include<string.h>
 
int main()
{
	char arr1[] = "1254594572@QQ.COM";
	char arr2[30] = { 0 };
	strcpy(arr2, arr1);
 
	const char* arr3 = "@.";
 
	printf("账号:%s\n", strtok(arr2, arr3));
	//找到第一个标记停止
	printf("服务商:%s\n", strtok(NULL, arr3));
	//从保存好的位置开始往后找
	printf("网址后缀:%s\n", strtok(NULL, arr3));
	//从保存好的位置开始往后找
 
	return 0;
}

        首先我们要知道,strtok 函数是会对数组本身进行操作的,所以我们为了保护原始数据,在定义并初始化好字符数组之后,又定义了一个新的数组并将原始数据拷贝过去,作为临时拷贝供我们进行操作。接着我们定义并初始化了分割符数组,函数将根据分割符数组 arr3 对 临时拷贝 arr2 进行分割第一次执行函数时之前没有标记,于是直接进行操作找到第一个标记并分割打印。此时就已经存在标记了,再连续两次找到前一次执行作下的标记按照分割符将数组分割完毕并打印。
        但是上面的代码风格较为简陋、复杂,我们可以将上面段代码优化为:

#include<stdio.h>
#include<string.h>
 
int main()
{
	char arr1[] = "1254594572@QQ.COM";
	char arr2[30] = { 0 };
	strcpy(arr2, arr1);
 
	const char* arr3 = "@.";
 
	char* str = NULL;
	for (str = strtok(arr2, arr3); str != NULL; str = strtok(NULL, arr3))
	{
		printf("%s\n", str);
	}
 
	return 0;
}

ps:若字符串中不存在更多的标记,则返回 NULL 指针。

10.strerror函数:

ffac4da78a99485581c730e832f3f151.png

         strerror函数(string error)的作用:返回错误码对应的信息。即根据接收到的错误码(错误码errno为全局变量),返回错原因的详细信息。

下面是strerror函数的基本用法:

int main()
{
    int i = 0;
    for (i = 0; i <= 4; i++)
    {
        printf("错误原因:%s\n", strerror(i));
    }
    return 0;
}

11.memcopy函数:

8f90992d341241bda5ba88ac9f8f8ac4.png

memcpy函数(memory copy)的作用:从源内存空间向目的内存空间拷贝限制数量(单位是字节)的数据。它与 strcpy 函数类似,作用均为拷贝数据,不同的是 strcpy 仅仅只操作字符串故会在结束标识符 ' \0 ' 处停止,而 memcpy 函数操作的是内存,内存中的数据是相邻的,故不会在结束标识符处停止。

下面是memcpy函数的基本用法:

#include<stdio.h>
#include<string.h>

int main()
{
    int arr1[] = { 1,2,3,4,5,6 };
    int arr2[5] = { 0 };

    for (int i = 0; i < 5; i++)
    {
        printf("%d ", arr2[i]);
    }
    printf("\n");
    //mencpy(目的地址,源地址,拷贝的大小)
    memcpy(arr2, arr1, 16);

    for (int i = 0; i < 5; i++)
    {
        printf("%d ", arr2[i]);
    }
    return 0;
}

         我们首先创建并初始化了两个整形数组,接着打印出数组 arr2 内数据的存放情况。紧接着我们通过内存拷贝函数,将数组 arr1 内的前20个字节的数据拷贝给了 arr2数组整型数组内每个数据元素所占的内存空间为4个字节,20个字节即将数组 arr1 中的前五个数据元素拷贝给了数组 arr2。最后再次打印数组 arr2 中的数据,验证拷贝结果。

ps:如果源内存空间和目标内存空间有任何重叠,复制的结果都是未定义的。

12.memmove函数:

c9df8557d883487b9a228df6ae0ef1ce.png

         memmove函数(memory move)的作用:弥补 memcpy 函数的不足,主要用于处理内存的重叠部分。即如果源空间和目标空间出现重叠,就得使用 memmove 函数来进行处理。

下面是memmove函数的基本用法:

#include<stdio.h>
#include<string.h>

int main()
{
    int arr1[] = { 1,2,3,4,5,6,7,8,9 };
    

    for (int i = 0; i < 7; i++)
    {
        printf("%d ", arr1[i]);
    }
    printf("\n");
    //mencpy(目的地址,源地址,拷贝的大小)
    memmove(arr1 + 2, arr1, 20);

    for (int i = 0; i < 7; i++)
    {
        printf("%d ", arr1[i]);
    }
    return 0;
}

        这个函数与 memcpy 函数除处理对象不同外,语法结构和使用场景等都极其类似,这里也就不再做过多赘述。

13.memcmp函数:

275b55d55c8b436b82db79ef8330c98f.png

         memcmp 函数(memory compare)的作用与 strcmp 函数的作用类似,不过 memcmp 函数是从内存的角度以字节为单位进行处理,故 memcmp 函数同样需要第三个参数进行限制,而不会在结束标识符 ' \0 ' 处停止比较。其它方面也就不再做过多赘述。 

memcmp 函数的基本使用方式:

#include<stdio.h>
#include<string.h>
 
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9 };
	int arr2[] = { 1,2,3,4,5,9,6,7,8 };
 
	int ret = memcmp(arr2, arr1, 24);
 
	if (ret > 0)
	{
		printf("arr1 < arr2\n");
	}
	else if (ret == 0)
	{
		printf("arr1 = arr2\n");
	}
	else
	{
		printf("arr1 > arr2");
	}
 
	return 0;
}

二、总结:

        本文到此就结束了,主要为大家整理并讲解了常用字符串操作函数,希望对大家有所帮助,同时本文仍有许多不足之处,欢迎各位小伙伴们随时批评指正!

  • 20
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
C语言进阶高级编程PDF》是一本以C语言为主题的进阶级别编程书籍,旨在帮助读者提升C语言编程水平并掌握更高级的编程技巧和思维方式。 该PDF书籍的内容包括但不限于以下几个方面: 1. 数据结构与算法:介绍了常用数据结构(如链表、栈、队列、树等)的实现原理和使用方法,以及一些常见算法(如排序、查找等)的实现。 2. 指针与内存管理:探讨了指针的概念、指针和数组、指针和函数等相关内容,以及如何进行动态内存管理和资源释放。 3. 文件操作:介绍C语言中对文件的读写操作方法,包括文件的打开、写入、读取和关闭等。 4. 高级函数和宏:介绍C语言中的函数指针、回调函数、宏定义等高级编程技巧,以及如何利用宏定义提高代码的可读性和可维护性。 5. 库函数和系统调用:详细介绍C语言标准库函数和一些系统调用的使用方法,如字符串处理函数、数学函数、时间函数等。 6. 多线程和进程:探讨了C语言中多线程和进程的概念和使用方法,包括线程的创建与同步、进程的创建与间通信等。 通过阅读《C语言进阶高级编程PDF》,读者可以拓宽自己的C语言知识面,学习更高级和更复杂的编程技巧,提升自己在C语言编程方面的能力和应用水平。无论是对于初学者还是有一定经验的C语言开发者来说,这本书都是一本很有价值的参考资料。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值