<<C>>深度理解字符串函数<string.h> 模拟实现

简介: <<C>>深度理解字符串函数<string.h> 模拟实现

1. (string length)

1.1功能

计算字符串的长度

size_t strlen ( const char * str );

注意:不计算  ' \0 '                         例如:

char arr[]="nihenNB"
//我们知道这种初始字符串,编译器会在后面自动添加'\0'
//长度为7+1=8
printf("%d",strlen(arr));
//打印的结果为7,不计算'\0'

1.2模拟实现strlen

(一共有三种方法),可以对比一下

int my_strlen(char* arr)//计数器的方式
{
  int n = 0;
  while (*arr != '\0')
  {
    n++;
    arr++;
  }
  return n;
}
int my_strlen2(char* arr)//不创建临时变量的计数器方法
{
  //试用嵌套  
  if (*arr == '\0')
  {
    return 0;
  }
  else
  {
    return 1 + my_strlen2(arr + 1);
  }
}
int my_strlen3(char* arr)//使用指针的方法
{
  char* p = arr;
  while (*p++ != '\0')
  {
    ;
  }
  return p - arr - 1;
}
int main()//模拟实现strlen
{
  char arr[] = "i am shan haonan.";
  printf("%d\n", my_strlen3(arr));
  return 0;
}

2.strcpy(string copy)

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

2.1功能:复制字符串


返回目的指针,可以实现链式访问(复制的地方,复制的内容)

注意:


源字符串必须以 '\0' 结束。

会将源字符串中的 '\0' 拷贝到目标空间。

目标空间必须足够大,以确保能存放源字符串。

目标空间必须可变。

学会模拟实现。

2.2模拟实现

#include<stdio.h>
#include<string.h>
char* my_strcpy(char* arr2,char *arr1)//返回的值为arr2
{
  //while (*arr1!='\0')
  //{
  //  *arr2 = *arr1;
  //  arr2++;
  //  arr1++;
  //}
  //上述代码可以简化内下:
  char* arr = arr2;
  while (*arr2++ = *arr1++)
  {
    ;
  }
  return arr;
}
int main()//模拟实现strcpy
{
  char arr1[] = "hello";
  char arr2[20] = "0";
  //strcpy(arr2, arr1);//将arr1的内容拷贝到arr2中
  my_strcpy(arr2, arr1);
  printf("%s\n", arr2);
  return 0;
}


3.strcat

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

3.1功能


目标空间的后面添加新的内容 

源字符串必须以 '\0' 结束。

目标空间必须有足够的大,能容纳下源字符串的内容。

目标空间必须可修改。

字符串自己给自己追加,如何?

3.2模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcat(char* des, char* res)
{
  assert(des != NULL);
  assert(res != NULL);
  char* p = des;
  while (*des!= '\0')
  {
    des++;
  }
  //while (*res!='\0')//字符串复制
  //{
  //  *des = *res;
  //  des++;
  //  res++;
  //}
  //上述代码简化版本:
  while (*des++ = *res++)
  {
    ;//当赋值/0的时候,括号内相当于0为假,自然就结束了循环
    //但是要注意结束循环的时候 des和res又一次++
  }
  return p;
}
int main()//模拟实现strcat
{
  char arr[20] = "helllo";
  char arr2[] = " sb";
  //printf("%s\n",strcat(arr, arr2));
  printf("%s\n",my_strcat(arr, arr2));
  return 0;
}


4.strcmp

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

3.1功能

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

第一个字符串等于第二个字符串,则返回0

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

3.2模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strcmp(char* arr1, char* arr2)
{
  assert(arr1 && arr2);
  while (*arr1 == *arr2)
  {
    arr1++; 
    arr2++;
  }
  return (*arr1 - *arr2);
}
int main()//模拟实现strcmp
{
  char arr1[] = "hello";
  char arr2[] = "hallo";
  //如果arr1>arr2返回>0
  //printf("%d", strcmp(arr1, arr2));
  printf("%d", my_strcmp(arr1, arr2));
  return 0;
}

5.strstr

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

5.1功能:

判断是否str2是str1的字串,如果是,则该函数返回str2在str1中首次出现的地址;

否则,返回NULL。

5.2模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strstr(char* des, char* res)
{
  assert(des && res);
  char* flag = des;
  while (*flag!='\0')
  {
    char* s1 = flag;
    char* s2 = res;
    while (*s1 == *s2)
    {
      s1++;
      s2++;
      if (*s2 == '\0')
      {
        return flag;
      }
    }
    flag++;
  }
  return NULL;
}
int main()//模拟实现strstr,查找是否存在子字符串
{
  char arr[] = "abcdedef";
  char arr2[] = "def";
  //printf("%s\n",strstr(arr, arr2));//返回的是arr的内部字串的地址
  my_strstr(arr, arr2);
  printf("%s\n", my_strstr(arr, arr2));
  return 0;
}


相关文章
|
JavaScript 前端开发 C++
lodash库——封装好的string字符串函数
lodash库——封装好的string字符串函数
208 0
|
C语言
C语言string库之常用字符和字符串函数详解
C语言string库之常用字符和字符串函数详解
|
测试技术
常用字符串函数 #include<string.h>与#include<stdio.h>
常用字符串函数 #include<string.h>与#include<stdio.h>
198 1
模拟实现字符串函数以及内存函数(均包含在头文件“string.h“中)
①不限字符个数型(strlen, strcpy, strcmp, strcat,strstr) ②限字符个数型(strncpy, strcmp, strncat) ③内存型(memcpy, memmove, memset)
206 0
|
1月前
|
编解码 Java 开发者
Java String类的关键方法总结
以上总结了Java `String` 类最常见和重要功能性方法。每种操作都对应着日常编程任务,并且理解每种操作如何影响及处理 `Strings` 对于任何使用 Java 的开发者来说都至关重要。
218 5
|
5月前
|
存储 编译器 C语言
关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论
你真的了解string的'\0'么?你知道创建一个string a("abcddddddddddddddddddddddddd", 16);这样的string对象要创建多少个对象么?你知道string与vector进行扩容时进行了怎么的操作么?你知道怎么求Vector 最大 最小值 索引 位置么?
126 0
|
8月前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
194 11
|
8月前
|
Java
课时14:Java数据类型划分(初见String类)
课时14介绍Java数据类型,重点初见String类。通过三个范例讲解:观察String型变量、&quot;+&quot;操作符的使用问题及转义字符的应用。String不是基本数据类型而是引用类型,但使用方式类似基本类型。课程涵盖字符串连接、数学运算与字符串混合使用时的注意事项以及常用转义字符的用法。
216 9
|
8月前
|
存储 JavaScript Java
课时44:String类对象两种实例化方式比较
本次课程的主要讨论了两种处理模式在Java程序中的应用,直接赋值和构造方法实例化。此外,还讨论了字符串池的概念,指出在Java程序的底层,DOM提供了专门的字符串池,用于存储和查找字符串。 1.直接赋值的对象化模式 2.字符串池的概念 3.构造方法实例化
134 1
|
Java
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
本文深入探讨了Java中方法参数的传递机制,包括值传递和引用传递的区别,以及String类对象的不可变性。通过详细讲解和示例代码,帮助读者理解参数传递的内部原理,并掌握在实际编程中正确处理参数传递的方法。关键词:Java, 方法参数传递, 值传递, 引用传递, String不可变性。
262 1
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性