• 字符函数和字符串函数


    前言

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

    一、求字符串长度

    strlen(求字符串长度)

    strlen函数介绍:
    在这里插入图片描述
    1.strlen函数,以‘\0’作为字符串的结束标志,strlen函数返回的是在字符串中‘\0’,之前出现的字符个数,不包含‘\0’。

    strlen功能展示:

    int main()
    {
    	char arr[] = "abcdef";
    	int ret = strlen(arr);
    	printf("%d ", ret);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    strlen的模拟实现:my_strlen:

    int my_strlen(char* arr)
    {
    	int count = 0;
    	while (*arr)
    	{
    		count++;
    		arr++;
    	}
    	return count;
    }
    
    int main()
    {
    	char arr[] = "abcdef";
    	int ret = my_strlen(arr);
    	printf("%d", ret);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    二、长度不受限制的字符串函数

    1.strcpy(字符串复制)

    strcpy函数介绍:
    在这里插入图片描述
    destination:目的地
    source:源头

    1.源字符串必须有‘\0’为结束标志
    2.也会将源字符串中的‘\0’拷贝到目标空间中
    3.目标空间必须足够大,以确保能存放源字符串,而且目标空间必须可变。

    strcpy功能展示:

    int main()
    {
    	char arr1[] = "abc";
    	char arr2[] = "xxxxxx";
    	printf("%s", strcpy(arr2, arr1));
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    strcpy的模拟实现:my_strcpy

    char* my_strcpy(char* det, const char* src)
    {
    	char* ret = det;
    	assert(det);
    	assert(src);
    	while (*src)
    	{
    		*det++ = *src++;
    	}
    
    	return ret;
    }
    int main()
    {
    	char arr1[20] = "hello world";
    	char arr2[] = "xxx";
    	my_strcpy(arr1, arr2);
    	printf("%s", arr1);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2.strcat(字符串拼接)

    strcat函数介绍:
    在这里插入图片描述
    1.源字符串必须以’\0’结束
    2.目标空间必须足够大,以确保能存放源字符串
    3.目标空间必须可修改
    函数功能展示:

    int main()
    {
    	char arr1[20] = "abc";
    	char arr2[] = "def";
    	printf("%s", strcat(arr1, arr2));
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    strcat函数模拟实现:

    
    char* my_strcat(char*dest, const char *src)
    {
    	assert(dest && src);
    
    	char* ret = dest;
    	//1. 找目标空间中的\0
    	while (*dest)
    	{
    		dest++;
    	}
    	while (*dest++ = *src++)
    	{
    		;
    	}
    	return ret;
    }
    
    int main()
    {
    	char arr1[20] = "hello ";
    	char arr2[] = "world";
    	my_strcat(arr1, arr2);
    
    	printf("%s\n", arr1);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    3.strcmp

    strcmp函数功能介绍:
    在这里插入图片描述
    在这里插入图片描述

    • 如果第1个字符串大于第2个字符串,则返回大于0的数字。
    • 如果第1个字符串等于第2个字符串,则返回0。
    • 如果第1个字符串小于第2个字符串,则返回小于0的数字。
    int main()
    {
    	char arr1[] = "abc";
    	char arr2[] = "abf";
    	int ret = strcmp(arr1, arr2);
    	printf("%d ", ret);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    strcmp的模拟:my_strcmp

    int main()
    {
    	char arr1[] = "abc";
    	char arr2[] = "abf";
    	int ret = strcmp(arr1, arr2);
    	printf("%d ", ret);
    	return 0;
    }
    
    int my_strcmp(const char* str1, const char* str2)
    {
    	assert(str1 && str2);
    
    	while (*str1 == *str2)
    	{
    		if (*str1 == '\0')
    			return 0;
    
    		str1++;
    		str2++;
    	}
    
    	return (*str1 - *str2);
    }
    //VS
    //> 1
    //= 0
    //< -1
    //
    
    int main()
    {
    	int ret = my_strcmp("bbq", "bcq");
    	if (ret>0)
    		printf(">\n");
    
    	printf("%d\n", ret);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    三、长度受限制的字符串函数

    1.strncpy

    strncpy功能介绍:
    在这里插入图片描述

    • 拷贝num个字符从源字符串中到目标空间。
    • 如果源字符串的长度小于num,则拷完源字符串之后在目标的后面追加0直到num个
    int main()
    {
    	char arr1[20] = "abcdef";
    	char arr2[] = "xxx";
    	char* ret=strncpy(arr1, arr2,3);
    	printf("%s", ret);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    2.strncat

    strncat函数功能的介绍:
    在这里插入图片描述
    从字符串追加字符

    • 将源的第一个数字字符追加到目标,外加一个终止空字符。
    • 将源的第一个数字字符追加到目标,外加一个终止空字符。如果源中 C 字符串的长度小于 num,则仅复制终止空字符之前的内容。
    int main()
    {
    	char arr1[20] = "abcdef";
    	char arr2[] = "xxx";
    	char* ret=strncat(arr1, arr2,3);
    	printf("%s", ret);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    3.strncmp

    strncmp函数功能介绍:
    在这里插入图片描述
    在这里插入图片描述

    
    int main()
    {
    	char arr1[20] = "abcdef";
    	char arr2[] = "abd";
    	int ret=strncmp(arr1, arr2,3);
    	printf("%d", ret);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    四、字符串查找

    1.strstr

    strstr函数功能介绍:
    在这里插入图片描述
    在这里插入图片描述
    理解:这个字符串函数就是在一个字符串里面查找子字符串如果能够找到目标子字符串,就返回子字符串的首元素地址,依次往下读取,直到读取到‘\0’为止。
    看下例代码:

    int main()
    {
    	char str[] = "This is a simple string";
    	char* pch;
    	pch = strstr(str, "simple");
    	printf("%s", pch);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    2.strtok

    strtok函数功能介绍:
    在这里插入图片描述
    将字符串拆分为标记
    例:
    char* strtok (char* str,const char* sep)

    • sep参数是个字符串,定义了用作分隔符的字符集合
    • 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
    • strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改
      变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
    • strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
    • strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
    • 如果字符串中不存在更多的标记,则返回 NULL 指针。
      例如:
    /* strtok example */
    #include 
    #include 
    int main()
    {
    	char str[] = "- This, a sample string.";
    	char* pch;
    	printf("Splitting string \"%s\" into tokens:\n", str);
    	pch = strtok(str, " ,.-");
    	while (pch != NULL)
    	{
    		printf("%s\n", pch);
    		pch = strtok(NULL, " ,.-");
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述

    五、错误信息报告

    strerror

    strerror函数功能介绍:
    在这里插入图片描述
    在这里插入图片描述

    /* strerror example : error list */
    #include 
    #include 
    #include 
    
    int main()
    {
        FILE* pFile;
        pFile = fopen("unexist.ent", "r");
        if (pFile == NULL)
            printf("Error opening file unexist.ent: %s\n", strerror(errno));
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    六、内存操作函数

    1.memcpy

    memcpy函数功能介绍:

    • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
    • 这个函数在遇到 ‘\0’ 的时候并不会停下来。
    • 如果source和destination有任何的重叠,复制的结果都是未定义的
    /* memcpy example */
    #include 
    #include 
    
    struct {
      char name[40];
      int age;
    } person, person_copy;
    
    int main ()
    {
      char myname[] = "Pierre de Fermat";
    
      /* using memcpy to copy string: */
      memcpy ( person.name, myname, strlen(myname)+1 );
      person.age = 46;
    
      /* using memcpy to copy structure: */
      memcpy ( &person_copy, &person, sizeof(person) );
    
      printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age );
    
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述

    2.memmove

    memmove函数的功能介绍:
    在这里插入图片描述

    • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
    • 如果源空间和目标空间出现重叠,就得使用memmove函数处理。
    /* memmove example */
    #include 
    #include 
    
    int main ()
    {
      char str[] = "memmove can be very useful......";
      memmove (str+20,str+15,11);
      puts (str);
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    3.memcmp

    memcmp的功能介绍:
    在这里插入图片描述

    /* memcmp example */
    #include 
    #include 
    
    int main ()
    {
      char buffer1[] = "DWgaOtP12df0";
      char buffer2[] = "DWGAOTP12DF0";
    
      int n;
    
      n=memcmp ( buffer1, buffer2, sizeof(buffer1) );
    
      if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);
      else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);
      else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);
    
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    七、内存操作函数的模拟实现:

    1.memcpy的模拟:

    void * memcpy ( void * dst, const void * src, size_t count) 
    { 
     void * ret = dst; 
     assert(dst); 
     assert(src); 
     /* 
     * copy from lower addresses to higher addresses 
     */ 
     while (count--) { 
     *(char *)dst = *(char *)src; 
     dst = (char *)dst + 1; 
     src = (char *)src + 1; 
     } 
     return(ret); 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2、memmove的模拟:

    void * memmove ( void * dst, const void * src, size_t count) 
    { 
     void * ret = dst; 
     if (dst <= src || (char *)dst >= ((char *)src + count)) { 
     /* 
     * Non-Overlapping Buffers 
     * copy from lower addresses to higher addresses 
     */ 
     while (count--) { 
     *(char *)dst = *(char *)src; 
     dst = (char *)dst + 1; 
     src = (char *)src + 1; 
     } 
     } 
     else { 
     /* 
     * Overlapping Buffers 
     * copy from higher addresses to lower addresses 
     */ 
     dst = (char *)dst + count - 1; 
     src = (char *)src + count - 1; 
     while (count--) { 
     *(char *)dst = *(char *)src; 
     dst = (char *)dst - 1; 
     src = (char *)src - 1; 
     } 
     } 
     return(ret); 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    好了,今天的分享就到这里了

    如果对你有帮助,记得点赞👍+关注哦!
    我的主页还有其他文章,欢迎学习指点。关注我,让我们一起学习,一起成长吧!
    好了,今天的分享就到这里了
    在这里插入图片描述

  • 相关阅读:
    异常处理流程
    (九)集合 - List
    实时即未来,大数据项目车联网之原始数据实时ELT流式任务流程总结【七】
    苹果宣布 2022 年 Apple 设计大奖得主
    uniapp实现防抖搜索
    【双指针】复写0
    用Python获取网络数据
    第7章 验证你的 Micro SaaS 应用程序构想
    阿里巴巴商品详情API接口(item_get-获得商品详情接口),阿里巴巴API接口
    Global Mapper 导出图层功能的妙用(重采样、设置文件类型、切片、按掩膜提取or裁剪……)
  • 原文地址:https://blog.csdn.net/weixin_75128035/article/details/133266266