【C语言进阶】字符串&内存函数

前言:

        字符串是一种非常重要的数据类型,但是C语言不存在显式的字符串类型,C语言中的字符串都以字符串常量的形式出现或存储在字符数组中。字符串常量适用于那些对它不做修改的字符串函数。同时,C 语言提供了一系列库函数来对操作字符串,这些库函数都包含在头文件 string.h 中。 

目录

一、求字符串长度

strlen

strlen函数的模拟实现

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

strcpy

strcpy函数的模拟实现

strcat

strcat函数的模拟实现

strcmp

strcmp函数的模拟实现

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

strncpy

strncpy函数的模拟实现

strncat

strncat函数的模拟实现

strncmp

strncmp函数的模拟实现

四、字符串查找

strstr

strstr函数的模拟实现

strtok

strtok函数的模拟实现

五、错误信息报告

strerror

六、字符操作

字符分类函数

 字符转换

七、内存操作函数

memcpy

memcpy函数的模拟实现

memmove

memmove函数的模拟实现

memset

memcmp


一、求字符串长度

strlen

size_t strlen ( const char * str );
  • 字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )
  • 参数指向的字符串必须要以 '\0' 结束
  • 注意函数的返回值为size_t,是无符号的( 易错 )
  • 学会strlen函数的模拟实现

源字符串必须以 '\0' 结束。 会将源字符串中的 '\0' 拷贝到目标空间。 目标空间必须足够大,以确保能存放源字符串。 目标空间必须可变。 学会模拟实现。

例1:

#include <stdio.h>
#include <string.h>
int main()
{
    int len1 = strlen("abcdef");
    printf("%d\n", len1); //6
    char arr[] = {'a','b','c','d','e','f'};
    //错误写法
    int len2 = strlen(arr);
    printf("%d\n", len2); //随机值
    return 0;
}

执行结果: 

例2:

int main()
{
    if(strlen("abc") - strlen("abcdef") > 0)
        printf("hehe\n");
    else
        printf("haha\n");
    system("pause");
    return 0;
}

执行结果:

 由于此时的strlen没有进行定义,它的默认类型为无符号类型,那么两个无符号数相加减最后得出的数是一个很大的数,所以最后的结果必然是大于0的

strlen函数的模拟实现

(1)计数器

#include <stdio.h>
#include <assert.h>
int my_strlen(const char *str)
{
    int count = 0;
    assert(str != NULL);
    while(*str != '\0')
    {
        count++;
        str++;
    }
    return count;
}
int main()
{
    int len = my_strlen("abcdef");
    printf("%d\n", len);
    return 0;
}

 (2)指针-指针

#include <stdio.h>
int my_strlen(const char *str)
{
	  const char *p = str;
	  while(*p != '\0')
	  {
	  	  p++;
	  }
	  return p-str;
}
int main()
{
	  int len = 0;
	  char arr[10]="abcdef";
	  len = my_strlen(arr);
	  printf("%d\n", len);
	  return 0;
}

(3)递归

不创建临时变量求字符串长度

#include<stdio.h>
int my_strlen(const char *str)
{
	  if(*str=='\0')
		    return 0;
	  else
  	    return 1+my_strlen(str+1);
}

int main()
{
    int len = 0;
	  char arr[10]="abcdef";
	  len = my_strlen(arr);
	  printf("%d\n", len);
    return 0;
}

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

strcpy

char* strcpy(char * destination, const char * source);
  • 将按源指向的 C 字符串复制到按目的地指向的阵列中,包括终止空字符 (并停止在那个时候) 
  • 源字符串必须以 '\0' 结束
  • 会将源字符串中的 '\0' 拷贝到目标空间
  • 目标空间必须足够大,以确保能存放源字符串
  • 目标空间必须可变。 学会模拟实现

例:

#include <stdio.h>
int main()
{
    char arr1[] = "abcdefghi";
    char arr2[] = "bit";

    //错误示范
    //char *arr1 = "abcdefghi";
    //p指向常量字符串,而常量字符串无法被修改
    //char arr2[] = {'b','i','t'};
    //由于此时没有给'\0',由于找不到'\0'会导致向后越界访问

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

strcpy函数的模拟实现

#include <stdio.h>
#include <assert.h>
char *my_strcpy(char *dest, const char *src)
{
    assert(dest != NULL);
    assert(src != NULL);
    char *ret = dest;
    //拷贝src指向的字符串到dest指向的空间,包含'\0'
    while(*dest++ = *src++)
    {
        ;
    }
    //返回目的的空间的初始地址
    return ret;//'\0'
}
int main()
{
    char arr1[] = "abcdefgh";
    char arr2[] = "bit";
    my_strcpy(arr1, arr2); 
    printf("%s\n", arr1);
    return 0;
}

strcat

char * strcat ( char * destination, const char * source );
  • 将源字符串的副本附加到目的地字符串。终止无效字符在目的地由源的第一个字符覆盖,并在源的末尾包含空字符由目的地两者的连结形成的新字符串
  • 源字符串必须以 '\0' 结束
  • 目标空间必须有足够的大,能容纳下源字符串的内容
  • 目标空间必须可修改
  • 字符串自己如何给自己追加

例: 

#include <stdio.h>
int main()
{
    char arr1[30] = "hello\0xxxxxxx";
    char arr2[] = "wolrd";
    strcat(arr1, arr2);
    printf("%s\n", arr1);
    //错误示范
    char arr3[] = "hello";
    char arr4[] = "world";
    strcat(arr3, arr4);
    printf("%s\n", arr3);
    //由于arr3数组没有定义空间大小
    //此时就开辟了'hello\0'6个字节
    //当arr4数组追加过去后就产生了越界访问,产生报错
    return 0;
}

调试结果: 

执行结果:

总结:此时我们可以看到,arr2数组内的的字符串从arr1数组中的'\0'开始进行追加

当arr2数组内的字符串追加过去后,后面的‘\0’也一并追加了过去

当目标空间不够大时,就会造成访问越界

strcat函数的模拟实现

#include <stdio.h>
#include <assert.h>
char *my_strcat(char *dest, const char *src)
{
    assert(dest != NULL);
    assert(src);
    char *ret = dest; 
    //1.找到目的字符串的'\0'
    while(*dest != '\0')
    {
        dest++;
    }
  • 45
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 41
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HyDraZya

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值