一篇文章带你解决“字符串函数”

目录

一、strlen函数

二、strcpy函数

三、strcat函数

四、strcmp函数

五、strncpy函数

六、strncat函数

七、strncmp函数

八、strstr函数

九、strtok函数

十、strerror函数


        在编程的过程中,我们经常要处理字符和字符串,为了⽅便操作字符和字符串,C语⾔标准库中提供了 ⼀系列库函数。在上篇文章已讲解字符函数,本篇文章我们将讲解字符串函数。

        使用此类字符串函数需要引用头文件——#include<string.h>

        注意:在下文中,字符指针source指向的字符串,称为源字符串字符指针destination指向的字符串,称为目标字符串

一、strlen函数

size_t strlen ( const char * str );

        函数接收的参数类型是字符指针,返回值是无符号整数。

        strlen函数的作用是:传递一个字符的地址给函数,然后从这开始向后找字符,找到'\0'为止,得到'\0'之前的字符总个数,并将这个值作为返回值返回。

        因为得到的结果是非负整数,所以strlen函数的返回值是无符号整数。

        同时因为字符串本质上是一个匿名字符数组可以视为数组名。字符串除赋值给字符数组之外,都被作为数组名使用,而数组名在大多数情况下视为数组首元素的指针,所以strlen("AB")本质上传递的是字符'A'的地址。

        所以strlen函数最常用的作用是计算字符串的长度。以下是具体的代码演示:

#define _CRT_SECURE_NO_WARNINGS

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

int main()
{
	char* ret = "apple";
	size_t a = strlen(ret);
	printf("%zd", a);//5
	return 0;
}

二、strcpy函数

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

        函数接收的参数类型是两个字符指针,返回值也是字符指针。

        strcpy函数的作用是:将source指向的字符串复制到destination指向的数组中,包括结束的'\0'字符,并在该点停止。

        举个列子:source指向的字符串是"ABC",destination指向的字符串是"abcdef"。将source指向的字符串复制到destination指向的字符串之后,destination指向的字符串为"ABC\0ef"。它会从前面做一个覆盖,此时打印destination指向的字符串,得到的结果是"ABC"。并不是说它剩余的部分消失了,只是前面有个'\0'导致后面无法打印。

        strcpy函数的返回值是字符指针,返回的是复制结束后,destination指向字符串的地址。

        我们在使用这个函数时要注意几个点:

        第一,源字符串必须以 '\0' 结束;复制时会将源字符串中的 '\0' 拷⻉到⽬标空间。

        第二,⽬标空间必须⾜够⼤,以确保能存放源字符串;⽬标空间必须可修改。        

        以下是具体的代码演示:

#define _CRT_SECURE_NO_WARNINGS

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

int main() 
{
    char source[] = "ABC";
    char destination[20] ="abcdef";
    
    strcpy(destination, source);
    printf("复制后的字符串: %s\n", destination);//ABC\0ef

    char(*p)[] = strcpy(destination, source);
    printf("%s\n", *p);

    return 0;
}

三、strcat函数

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

        函数接收的参数类型是两个字符指针,返回值也是字符指针。

        strcat函数的作用是:将源字符串的副本追加到目标字符串。destination中结束的'\0'字符被source的第一个字符覆盖,追加完成后,函数会在新字符串的末尾添加字符'\0',作为结束标志。

        举个列子:source指向的字符串是"ABC",destination指向的字符串是"abcdef"。追加后,destination指向的字符串是"abcdefABC",且末尾包含'\0'

        strcpy函数的返回值是字符指针,返回的是追加结束后,destination指向字符串的地址。

        我们在使用这个函数时要注意几个点:

        第一,源字符串必须以'\0' 结束;⽬标字符串中也得有'\0' ,否则无法知道追加从哪开始。

        第二,⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容;⽬标空间必须可修改。

        第三这个函数中,字符串不能给自己追加。因为源字符串的'\0'被覆盖掉了,所以用源字符串追加,就不会有'\0',就无法结束。同时因为自己的字符串长度一直在变长,所以无法追加到终点,会一直无限循环,直到程序报错。虽然在vs2022中,这样操作可以得到想要的结果,但是不建议这样去使用。

        以下是具体的代码演示:

#define _CRT_SECURE_NO_WARNINGS

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

int main() 
{
    char source[] = "ABC";
    char destination[20] ="abcdef";
    
    strcat(destination, source);
    printf("追加后的字符串: %s\n", destination);//abcdefABC

    return 0;
}

四、strcmp函数

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

        函数接收的参数类型是两个字符指针,返回值是整型。

        strcmp函数的作用是:从每个字符串的第一个字符开始比较,如果它们彼此相等,则继续比较下对,直到字符不同或到达终止空字符。

        比较后得到的返回值:第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字;第⼀个字符串等于第⼆个字符串,则返回0;第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字判断两个字符串的大小,⽐较的是两个字符串中对应位置上字符ASCII码值的⼤⼩。

        也就是说大小的评定,不是字符串的长度,而是对应位置上的字符的大小。

        以下是具体的代码演示:

#define _CRT_SECURE_NO_WARNINGS

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

int main() 
{
    char source[] = "abc";
    char destination[20] ="abbbew";
    
    int ret = strcmp(source, destination);
    if (ret > 0){
        printf("字符串abc大\n");
    }
    else if (ret = 0) {
        printf("两个字符串一样大\n");
    }
    else {
        printf("字符串abbbew大\n");
    }

    return 0;
}

五、strncpy函数

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

        函数接收的参数类型是两个字符指针和一个无符号整数,返回值是字符指针。

       strncpy函数的作用是:将源字符串的前num个字符复制到目标字符串。如果在复制num个字符之前已到达源字符串的末尾,则在目标字符串中用'\0'填充,直到总共写入num个字符为止。

        它与strcpy函数的区别就在于,strncpy函数固定了复制的个数,即便是源字符串不够,也会用'\0'去填充。

        strncpy函数的返回值是字符指针,返回的是复制结束后,destination指向字符串的地址。

        以下是具体的代码演示:

#define _CRT_SECURE_NO_WARNINGS

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

int main()
{
    char source[] = "ABC";
    char destination[20] = "abcdef";

    strncpy(destination, source, 5);
    printf("复制后的字符串: %s\n", destination);//ABC\0\0f

    char(*p)[] = strncpy(destination, source, 5);
    printf("%s\n", *p);//ABC\0\0f

    return 0;
}

六、strncat函数

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

        函数接收的参数类型是两个字符指针和一个无符号整数,返回值是字符指针。

        strncat函数的作用是:将源字符串的前num个字符追加到目标字符串,再追加⼀个'\0'字符。如果源字符串的⻓度⼩于num,只会将源字符串中到’\0'的内容追加到目标字符串。

        它与strcat函数的区别就在于,strncat函数固定了追加的个数。但是对于strncat函数,如果源字符串的字符数量小于num,那么只追加到源字符串的'\0',这是与strncpy函数不同的地方

        同时注意一点,任何追加都是从一个'\0'开始追加

        使用strncat函数,就可以自己给自己追加,因为长度是固定的,不会无限循环。

        strncat函数的返回值是字符指针,返回的是复制结束后,destination指向字符串的地址。

        以下是具体的代码演示:

#define _CRT_SECURE_NO_WARNINGS

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

int main()
{
    char source[] = "ABC";
    char destination[20] = "abcdef";

    strncat(destination, source, 2);
    printf("追加后的字符串: %s\n", destination);//abcdefAB

    return 0;
}

七、strncmp函数

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

        函数接收的参数类型是两个字符指针和一个无符号整数,返回值是整型。

        strncmp函数的作用是:⽐较str1和str2的前num个字符,如果相等就继续往后⽐较,最多⽐较num个字符。如果提前发现不⼀样,就提前结束;如果num个字符都相等,就是相等返回0。

        它比较后得到的返回值情况,与strcmp函数是一样的。它们唯一的不同就是,strncmp限定了最大的比较个数

        以下是具体的代码演示:

#define _CRT_SECURE_NO_WARNINGS

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

int main() 
{
    const char s1[] = "abced";
    const char s2[] = "abcde";
    int result = strncmp(s1, s2, 3);

    if (result == 0) {
        printf("s1和s2的前3个字符相同\n");//运行后是这个
    }
    else if (result < 0) {
        printf("s1的前5个字符小于s2的前3个字符\n");
    }
    else {
        printf("s1的前5个字符大于s2的前3个字符\n");
    }

    return 0;
}

八、strstr函数

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

        函数接收的参数类型是两个字符指针,返回值也是字符指针。

        strstr函数的作用是:在字符串str1中找字符串str2是否出现。

        如果出现,函数返回字符串str2在字符串str1中第⼀次出现的位置的字符指针;如果没出现,则返回空指针NULL。

        字符串的⽐较匹配不包含'\0'字符,以'\0'作为结束标志。也就是说比较的字符串中,'\0'不是要去匹配的对象,只是一个结束标志。

        以下是具体的代码演示:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>
int main()
{
	char str[] = "This is a simple string";
	char* pch;
	pch = strstr(str, "simple");
	printf("%s\n", pch);
	return 0;
}

九、strtok函数

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

        函数接收的参数类型是两个字符指针,返回值也是字符指针。

        strtok函数的作用是:按照delimiters中定义的分隔符,将字符串str分割成一系列的标记,每次调用strtok会返回下一个标记。

       第二个参数delimiters指向一个字符串,定义了用作分割符的字符集合,如char* ret = "!@"。

        第一个参数str指向一个字符串,它包含了0个或多个由delimiters字符串中⼀个或多个分隔符分割的标记,如char arr[] = "192!@168!16@111"。

        strtok函数找到str中的下⼀个标记,并将其⽤'\0'结尾,也就是将这个标记后面的一个分隔符替换为'\0',同时返回⼀个指向这个标记的指针。

        如果说这个标记后面有两个分割符,则后一个不会被'\0'代替,同时在下一次寻找时也会被忽略,因为strtok函数找的是下一个标记

        用上面的两个字符串举个例子,如果第一次调用strtok(arr, ret);,此时找第一个标记,即返回"192",同时将后面的一个分隔符变成'\0'。如果再次调用strtok,就返回下一个标记"168",同时后面的一个分隔符变成'\0'。那么此时字符串就变成"192\0@168\016@111"

       我们往后找,找的是一个完整的标记,而不是分隔符。

        在第一次调用中,我们是使用一个字符串作为函数的参数。但在后续调用中,该函数需要一个 NULL指针,并以最后一个标记结束后的位置作为扫描的新起始位置。即第二次以及后续的strtok函数调用,应该是strtok(NULL, ret)。

        如果后续不存在更多的标记,就返回空指针NULL。

        我们做个小总结:

        ①strtok找的是下一个标记,第一次寻找时,函数调用是strtok(arr, ret);,第二次及以后寻找的时候,函数调用是strtok(NULL, ret);

        ②如果能找到标记,返回值为标记;如果后续找不到标记,返回的是空指针NULL。同时标记后面的一个分隔符回被替换成'\0'

        以下是具体的代码演示:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>
int main()
{
	char arr[] = "192!@168!16@111";
	char* sep = "!@";
	char* str = NULL;
	for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
	{
		printf("%s\n", str);
	}
	return 0;
}

十、strerror函数

char * strerror ( int errnum );

        函数接收的参数类型是整型,返回值是字符指针。使用此字符串函数,还需要使用头文件——#include<errno.h>。

        strerror函数的作用是:系统错误码转换为对应的错误信息字符串,帮助程序员更直观地理解程序运行过程中出现的错误。

       一般我们在调用strerror函数时,写法为:strerror(error)。 error是C语言和C++编程中一个非常重要的全局变量,用于表示程序运行过程中发生的错误码它会在每次函数调用出错时被覆盖更新为新的错误码

        strerror 函数的使用场景是在程序执行过程中遇到错误,但这些错误不会导致程序直接崩溃或异常终止,而是通过errno全局变量来记录错误信息,以便后续使用strerror函数将错误码转换为可读的错误信息字符串。

        常见的有两类错误:可恢复性错误不可恢复性错误

        可恢复性错误:这类错误通常不会使程序无法继续运行,只是某些操作没有按预期完成。例如文件打开失败、内存分配不足、网络连接超时等。程序可以针对这些错误进行相应的处理,如提示用户、尝试重新执行操作等。strerror 函数在这种情况下可以帮助开发者了解具体的错误原因。

        不可恢复错误:有些严重的错误虽然可能导致程序无法正常完成主要任务,但在程序终止前仍可以使用 strerror 输出错误信息,方便调试和定位问题。例如栈溢出、除数为零、严重的资源耗尽等。

        以下是具体的代码演示:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>

int main() 
{
    // 第一个错误:尝试打开不存在的文件
    int fd = open("nonexistent_file.txt", O_RDONLY);
    if (fd == -1) 
    {
        printf("First error: %s\n", strerror(errno));
    }

    // 第二个错误:尝试分配大量内存
    char* ptr = (char*)malloc(1000000000000);
    if (ptr == NULL) 
    {
        printf("Second error: %s\n", strerror(errno));
    }

    // 再次使用 strerror,此时打印的是第二个错误的信息
    printf("Final error printed: %s\n", strerror(errno));

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值