IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言string.h部分函数模拟实现(1) -> 正文阅读

[C++知识库]C语言string.h部分函数模拟实现(1)


本篇文章用于模拟实现 “string.h” 中的部分函数.

介绍

1.首先是一个计算字符串长度函数

  • strlen()

2.长度不受限的字符串

  • strcpy()
  • strcat()
  • strcmp()

3.长度受限的字符串

  • strncpy()
  • strncat()
  • strncmp()

4.最后是一个字符串匹配函数的暴力解决方式

  • strstr()

1.计算字符串长度函数

1.1 strlen()

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>

//typedef unsigned int     size_t;
size_t my_strlen(const char* str)//const 使得传入的str不会被改变
{
   //assert()用于防止传入空指针
   assert(str);
   const char* start = str;
   const char* end = str;
   while (*end != '\0')
   {
   	end++;
   }
   return end - start;
}

int main()
{
   char arr[] = "abc\0def";
   int a = my_strlen(arr);//3	strlen的返回值是无符号整型,所以用返回值运算时需要注意
   printf("%d\n",a);
   return 0;
}

2.长度不受限的字符串

2.1 strcpy()

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
//char* 返回值 返回目标数组的首地址 用于后续调用时可以直接用返回值调用数组
char* my_strcpy(char* dest,const char* src)//const 使得传入的str不会被改变
{
   //断言用于判断数组是否为空
   assert(dest);
   assert(src);
   char* ret = dest;
   while(*dest++ = *src++)
   {
   	//(*dest++ = *src++)的值就是*src的值当*src=='\0'是循环退出
   	;
   }
   return ret;
}

int main()
{
   char arr[10] = "*********";
   //char* p = "abcdef";//常量字符串	空间无法修改	与下相同
   const char* p = "abcdef";
   my_strcpy(arr,p);//拷贝	会拷贝到\0	如果目标空间的大小不够也会拷贝,会造成越界访问
   printf("%s\n", arr);
   return 0;
}

2.2 strcat()

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>

//char* 返回值 返回目标数组的首地址 用于后续调用时可以直接用返回值调用数组
char* my_strcat(char* dest, const char* src)//const 使得传入的str不会被改变
{
   //断言用于判断数组是否为空
   assert(dest);
   assert(src);
   char* ret = dest;
   while (*dest!='\0')
   {
   	dest++;
   	//先找到目标数组的\0处
   	;
   }
   while (*dest++ = *src++)
   {
   	//(*dest++ = *src++)的值就是*src的值当*src=='\0'是循环退出
   	;
   }
   return ret;
}

int main()
{
   char arr[20] = "hello";
   char arr2[] = "world";

   my_strcat(arr,arr2);//字符串追加函数	strcpy相似
   //arr 和 arr2 都需要有\0	先找到arr的\0人后向后追加,追加到arr2的\0
   //目标空间需要可修改	目标空间需要能够容纳下原字符串的内容
   printf("%s\n",arr);

   //注:此函数无法自己追加自己	因为当你追加时会覆盖掉原来的'\0'使得函数遇不到'\0',函数无法结束
   
   return 0;
}

2.3 strcmp()

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>

//char* 返回值 返回目标数组的首地址 用于后续调用时可以直接用返回值调用数组
int my_strcmp(const char* str1, const char* str2)//const 使得传入的str不会被改变
{
   //断言用于判断数组是否为空
   assert(str1&&str2);
   while (*str1==*str2)
   {
   	if(*str1=='\0')
   	{
   		return 0;
   	}
   	str1++;
   	str2++;
   }
   return *str1 - *str2;
   //直接返回差值
}

int main()
{
   char str1[] = "hello";
   char str2[] = "hello";

   //strcmp()比较的是对应位置上的字符的大小,而非长度
   //需要\0用于结束
   int a = my_strcmp(str1, str2);
   //a<0:str1<str2
   printf("%d\n", a);

   return 0;
}

3.长度受限的字符串

3.1 strncpy()

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>

//typedef unsigned int     size_t;
char* my_strncpy(char* dest,const char* src,size_t count)//const 使得传入的str不会被改变
{
   char* ret = dest;
   while (count && (*dest++ = *src++) != '\0')
   {
   	//正常赋值数组元素
   	count--;
   }
   if (count)
   {
   	//补充'\0'
   	while (--count)
   	{
   		*dest++ = '\0';
   	}
   }
   return ret;
}

int main()
{
   char arr[10] = "*********";
   //char* p = "abcdef";//常量字符串	空间无法修改	与下相同
   const char* p = "abcdef";
   my_strncpy(arr, p,8);//拷贝	会拷贝到\0	如果目标空间的大小不够也会拷贝,会造成越界访问
   //如果需要拷贝的数组内容不够会在目标数组后续拷贝位置补充'\0'
   printf("%s\n", arr);
   return 0;
}

3.2 strncat()

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>

//char* 返回值 返回目标数组的首地址 用于后续调用时可以直接用返回值调用数组
char* my_strncat(char* dest, const char* src,size_t num)//const 使得传入的str不会被改变
{
   //断言用于判断数组是否为空
   assert(dest);
   assert(src);
   char* ret = dest;
   while (*dest != '\0')
   {
   	dest++;
   	//先找到目标数组的\0处
   	;
   }
   while (num--)
   {
   	*dest++ = *src++;
   	//追加
   	;
   }
   *dest = '\0';
   //最后添加'\0'
   return ret;
}

int main()
{
   char arr[20] = "hello";
   char arr2[] = "world";

   my_strncat(arr, arr2,3);//字符串追加函数	追加结束之后会在后面追加一个'\0'
   //arr需要有\0	先找到arr的\0人后向后追加,与strcat不同的是,追加结束之后会自动在后面追加一个'\0'
   //目标空间需要可修改	目标空间需要能够容纳下原字符串的内容
   printf("%s\n", arr);

   //注:此函数可以自己追加自己	因为有参数控制追加次数

   return 0;
}

3.3 strncmp()

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>

//char* 返回值 返回目标数组的首地址 用于后续调用时可以直接用返回值调用数组
int my_strncmp(const char* str1, const char* str2, size_t count)//const 使得传入的str不会被改变
{
   //断言用于判断数组是否为空
   assert(str1 && str2);
   while (--count && *str1 == *str2)
   {
   	if (*str1 == '\0')
   	{
   		return 0;
   	}
   	str1++;
   	str2++;
   }
   if (count == 0) 
   {
   	return 0;
   }
   return *str1 - *str2;
   //直接返回差值
}

int main()
{
   char str1[] = "hello";
   char str2[] = "helo";

   //strncmp()与strcmp()相似
   //比较前n个字符
   int a = my_strncmp(str1, str2,3);
   //a<0:str1<str2:以此类推
   printf("%d\n", a);

   return 0;
}

4.长度受限的字符串

4.1 strstr()

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>

//char* 返回子串在字符串中首次出现的起始位置
char* my_strstr(const char* str1, const char* str2)//const 使得传入的str不会被改变
{
   const char* s1 = str1;
   const char* s2 = str2;
   const char* p = str1;
   //循环判断寻找
   while (*p)
   {
   	s1 = p;
   	s2 = str2;
   	while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
   	{
   		s1++;
   		s2++;
   	}
   	if (*s2 == '\0')
   	{
   		//返回类型不匹配,强转为返回类型
   		return (char*)p;
   	}
   	p++;
   }
   return NULL;
}

int main()
{
   char arr[] = "abcdef";
   char arr2[] = "bcd";
   char* p = my_strstr(arr,arr2);//在arr中找arr2	NULL为不存在	存在则返回子串在字符串中首次出现的起始位置
   //此处的实现方法为暴力实现
   printf("%s\n",p);

   return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-21 00:08:17  更:2022-09-21 00:10:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 14:55:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码