字符串函数和内存函数

文章目录

  • 字符串函数
    • strlen函数
      • 模拟实现
    • strcpy函数
      • 模拟实现
    • strcat函数
      • 使用
      • 模拟实现
    • strcmp函数
      • 使用
      • 模拟实现
    • strncpy函数
      • 使用
      • 模拟实现
    • strstr函数
      • 使用
      • 模拟实现
    • strtok函数
      • 使用
    • strerror函数
    • 使用
  • 内存函数
    • memset函数
    • 使用
    • memcmp函数
    • memcpy函数
      • 使用
      • 模拟实现
    • memmove函数
      • 使用
      • 模拟实现
    • 总结

字符串函数

strlen函数

size_t strlen ( const char * str );
返回值是size_t
头文件——#include<string.h>
计算字符串的长度
不包括\0

模拟实现

计数器

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{assert(str);size_t count = 0;while (*str != '\0'){count++;str++;}return count;
}
int main()
{char arr[] = { "abcdefg" };size_t n = my_strlen(arr);printf("%u\n", n);return 0;
}

指针-指针

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{assert(str);char* p = str;while (*p!='\0'){p++;}return p - str;
}int main()
{char arr[] = { "abcdefg" };size_t n = my_strlen(arr);printf("%u\n", n);return 0;
}

递归

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{assert(str);if (*str == '\0')return 0;elsereturn 1 + my_strlen(str+1);}
int main()
{char arr[] = { "abcdefg" };size_t n = my_strlen(arr);printf("%u\n", n);return 0;
}

strcpy函数

char * strcpy ( char * destination, const char * source );
dst是目标空间,src是要复制的内容
拷贝内容到指定对象中
要确保指定对象有足够大的空间去容纳,否则可能会导致缓冲区溢出
目标空间必须可修改,不可以是常量字符串;
源字符串必须以\0结束
复制会把src指向的字符串包括\0复制过去

模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{assert(dest && src);//确保不是野指针char* dest_ptr = dest;//初始化目标字符串的指针//遍历源字符串while (*src!='\0'){*dest_ptr++ = *src++;}//添加空终止字符*dest_ptr = '\0';return dest;
}int main()
{char src[] = "hahahaha";char dest[20];my_strcpy(dest, src);printf("%s\n", dest);return 0;
}

在这里插入图片描述

strcat函数

追加内容,连接两个字符串
会将src指向的字符串(不包括\0)复制过去
所以不能追加自己本身,会死循环
目标空间足够大
复制完后dest会自动添加’\0’;

使用

#include<stdio.h>
#include<string.h>
int main()
{char src[] = "hahahaha";char dest[20] = "lololo ";strcat(dest, src);printf("%s\n", dest);return 0;
}

在这里插入图片描述

模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcat(char* dest, const char* src)
{assert(dest && src);char* dest_end = dest;while (*dest_end != '\0'){dest_end++;}while (*src){*dest_end++ = *src++;}*dest_end = '\0';return dest;
}
int main()
{char src[] = "hahahaha";char dest[20] = "yayaya ";my_strcat(dest, src);printf("%s\n", dest);return 0;
}

在这里插入图片描述

strcmp函数

int strcmp ( const char * str1, const char * str2 );
== 返回值==
在这里插入图片描述
比较字符串的大小,逐个逐个比,比较的是ASCII值

使用

#include<stdio.h>
#include<string.h>
int main()
{char* p = "abc";char* q = "abd";int ret=strcmp(p,q);printf("%d", ret);return 0;
}

在这里插入图片描述
在这里插入图片描述

#include<string.h>
#include<assert.h>
int main()
{char* p = "abcf";char* q = "abc";int ret=strcmp(p,q);printf("%d", ret);return 0;
}

在这里插入图片描述

模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strcmp(const char* s1, char* s2)
{assert(s1 && s2);while(*s1==*s2){if(*s1=='\0')return 0;s1++;s2++;}/*if (*s1 > *s2){return 1;}elsereturn -1;*/return *s1 - *s2;
}
int main()  
{char* p = "abc";char* q = "abd";int ret=my_strcmp(p, q);/*printf("%d", ret);*/if (ret > 0){printf("p>q\n");}else if (ret == 0){printf("p=q\n");}else{printf("p<q\n");}return 0;}

strncpy函数

长度受限制
char * strncpy ( char * destination, const char * source, size_t num );
复制完成后dest目标字符串不会自动添加\0;需要手动确保dest以\0结尾
注意
如果src包含空字符,strcpy会停止复制,可能会导致目标字符串没有正确以空字符结尾

使用

#include<stdio.h>
#include<string.h>
int main()
{char src[] = "hahahaha";char dest[20];strncpy(dest, src, 5);dest[5] = '\0';printf("%s\n", dest);return 0;
}

在这里插入图片描述

模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src,int n)
{assert(dest && src);char* dest_ptr = dest;while ((*src != '\0')&& n>0){*dest_ptr++ = *src++;--n;}if (*src == '\0'){while (n > 0){*dest_ptr++ = '\0';--n;}}*dest_ptr = '\0';return dest;
}int main()
{char src[] = "hahahaha";char dest[20];my_strcpy(dest, src,5);printf("%s\n", dest);return 0;
}

strstr函数

const char * strstr ( const char * str1, const char * str2 );
char * strstr ( char * str1, const char * str2 );
字符串查找
用于在字符串中搜索子字符串,并返回子字符串第一次出现的位置。如果找不到子字符串,则返回 false

使用

int main()
{const char* p = "abcdff";;char* ret=strstr(p, "bcd");if (ret != NULL){printf("存在");}elseprintf("不存在");return 0;
}

模拟实现

#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* s1, const char*s2)//const确保s1.s2不动,刚开始的起始位置不变,要创建新的
{assert(s1 && s2);const char* str1 = s1;const char* str2 = s2;const char* p = s1;while (*p){str1= p;//p赋值给srt1,p就不动先str2 = s2;while (str1!='\0'&&str2!='\0' && *str1 == *str2){str1++;str2++;}if (*str2 == '\0'){return p;//返回搜索到的起始位置}p++;}
}
int main()
{char arr1[] = { "hellowuwen" };char arr2[] = { "lo" };char* ret = my_strstr(arr1, arr2);if (ret == NULL){printf("子串不存在\n");}else{printf("%s\n",ret);}return 0;
}

在这里插入图片描述

strtok函数

char * strtok ( char * str, const char * delimiters );
delim为分隔符字符(如果传入字符串,则传入的字符串中每个字符均为分割符)
函数返回值
成功:返回被分割出的字符串
失败:NULL
传入NULL,会在原来保存的位置继续往下找

使用

#include<stdio.h>
#include<string.h>
int main()
{const char* sep = ",.";char arr[] = "anfnvbj,nsndu.vns";char copy[30] = { 0 };strcpy(copy, arr);//char* ret = strtok(copy, sep);//if(ret!=NULL)//printf("%s\n", ret);//有记忆功能,就像static静态变量一样,出了函数变量不销毁,一直都在//ret=strtok(NULL, sep);//传NULL是为了继续往下找//printf("%s\n", ret);//ret = strtok(NULL, sep);//printf("%s\n", ret);//简化char* ret = NULL;for (ret = strtok(copy, sep); ret != NULL; ret = strtok(NULL, sep)){printf("%s\n", ret); }return 0;
}

strerror函数

char * strerror ( int errnum );
返回错误信息
必须包含的头文件include<error.h>
C语言的库函数,返回失败都会设置错误码

使用

举例,打开文件
FILE * fopen ( const char * filename, const char * mode );
一定要有#include<errno.h>

#include<errno.h>
int main()
{FILE* pf = fopen("test.text", "r");//同个文件夹里的相对路径if (pf == NULL){printf( "%s\n",strerror(errno));return 1;}else{}return 0;}

在这里插入图片描述

内存函数

memset函数

void * memset ( void * ptr, int value, size_t num );
用于将一段内存中的所有字节设置为特定的值。
初始化数组或者内存块
字节为单位来进行初始化

使用

#include<stdio.h>
#include<string.h>
int main()
{char arr[] = "hello wuwen";memset(arr + 6, 'd', 4);printf("%s\n", arr);
}

在这里插入图片描述

memcmp函数

int memcmp ( const void * ptr1, const void * ptr2, size_t num );
size_t num是要比较的最大字节数
区别strcmp:strcmp只作用与字符串,memcmp作用于任何类型

#include<stdio.h>
#include<string.h>
int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 1,4,2 };int ret=memcmp(arr1, arr2, 12);if (ret < 0){printf("arr1<arr2");}else if (ret == 0){printf("arr1=arr2");}elseprintf("arr1>arr2");return 0;
}

在这里插入图片描述

memcpy函数

void * memcpy ( void * destination, const void * source, size_t num );
size_t num是要复制的字节数

使用

#include<stdio.h>
#include<string.h>
int main()
{int  arr[] = { 1,2,3,4,5 };int dest[6] = { 0 };memcpy(dest, arr,20);for (int i = 0; i < 5; i++){printf("%d ", dest[i]);}return 0;
}

但是要在原数组里复制可行吗?
eg:memcpy(arr,arr+2,12),打印出来是3,4,5,4,5
也就是说在vs里对于内存覆盖的复制是可行的,但实际上呢
我们通过测试会发现,memcpy不能复制源和目标内存区域重叠的数组

模拟实现

#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{assert(dest && src);void* ret = dest;while (num--){*(char*)dest = *(char*)src;dest=(char*)dest+1;//dest是void*类型,不能直接解引用,不能直接+-;src=(char*)src+1;}return ret;//不能直接return dest,dest已经被++了//由于返回是目的的地址,所以要保存一下
}
int main()
{int src[] = { 1,2,3,4,5,6,7,8,9,10 };int dest[20] = { 0 };my_memcpy(dest, src, 24);for (int i = 0; i < 6; i++){printf("%d ", dest[i]);}return 0;
}

测试下能不能复制同内存的
本应该是1 2 1 2 3 4 5 6 9 10
在这里插入图片描述
所以有可能会复制不了,这是从前往后复制的,那从后往前呢?
在这里插入图片描述
是可以的,这就相当于是memmove

memmove函数

void * memmove ( void * destination, const void * source, size_t num );
memmove很好的解决了memcpy内存覆盖的问题

使用

#include<stdio.h>
#include<string.h>
int main()
{int src[] = { 1,2,3,4,5,6,7,8,9,10 };//int dest[20] = { 0 };memmove(src+2, src, 24);for (int i = 0; i < 10; i++){printf("%d ", src[i]);}return 0;
}

在这里插入图片描述

如何实现呢?

在这里插入图片描述

看重叠部分是被拷贝数据的前半部分还是后半部分

模拟实现

#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, const void* src, size_t num)
{assert(dest && src);void* ret = dest;if (dest < src){while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;//dest是void*类型,不能直接解引用,不能直接+-;src = (char*)src + 1;}}else{while (num--){*((char*)dest + num) = *((char*)src + num);}}return ret;
}
int main()
{int src[] = { 1,2,3,4,5,6,7,8,9,10 };//int dest[20] = { 0 };my_memmove(src+2, src, 24);for (int i = 0; i < 10; i++){printf("%d ", src[i]);}return 0;
}

总结

看完相信你对字符串函数和内存函数有了一定认识,有什么问题欢迎在评论区指出来~
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/271263.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【深度优先】【图论】【C++算法】2045. 到达目的地的第二短时间

作者推荐 视频算法专题 LeetCode2045. 到达目的地的第二短时间 城市用一个 双向连通 图表示&#xff0c;图中有 n 个节点&#xff0c;从 1 到 n 编号&#xff08;包含 1 和 n&#xff09;。图中的边用一个二维整数数组 edges 表示&#xff0c;其中每个 edges[i] [ui, vi] 表…

HCIP---IS-IS协议

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.IS-IS协议概述 IS-IS是一种基于链路状态的内部网关协议&#xff08;IGP&#xff09;&#xff0c;它使用最短路径优先算法&#xff08;SPF或Dijkstra&#xff09;进行路由计算。这种协议在自治…

[密码学]入门篇——加密方式

一、概述 加密方法主要分为两大类&#xff1a; 单钥加密&#xff08;private key cryptography&#xff09;&#xff1a;加密和解密过程都用同一套密码双钥加密&#xff08;public key cryptography&#xff09;&#xff1a;加密和解密过程用的是两套密码 历史上&#xff0c…

u盘里文件损坏无法打开怎么恢复?这样操作更简单

U盘已经成为我们传输和存储数据的重要工具。然而有时候我们可能会遇到U盘里的文件损坏无法识别的情况&#xff0c;这无疑给我们的工作和学习带来了不小的困扰。 那么面对这种情况应该如何应对呢&#xff1f;本文将为你介绍个实用的恢复方法&#xff0c;帮助你轻松解决U盘文件损…

【洛谷 P8662】[蓝桥杯 2018 省 AB] 全球变暖 题解(深度优先搜索+位集合)

[蓝桥杯 2018 省 AB] 全球变暖 题目描述 你有一张某海域 N N N \times N NN 像素的照片&#xff0c;. 表示海洋、 # 表示陆地&#xff0c;如下所示&#xff1a; ....... .##.... .##.... ....##. ..####. ...###. .......其中 “上下左右” 四个方向上连在一起的一片陆地组…

机器学习-面经

经历了2023年的秋招&#xff0c;现在也已经入职半年了&#xff0c;空闲时间将面试中可能遇到的机器学习问题整理了一下&#xff0c;可能答案也会有错误的&#xff0c;希望大家能指出&#xff01;另外&#xff0c;不论是实习&#xff0c;还是校招&#xff0c;都祝福大家能够拿到…

国内哪个工具可以平替chatgpt?国内有哪些比较好用的大模型gpt?

我自己试用了很多的平台&#xff0c;发现三个比较好的大模型平台&#xff0c;对普通用户也比较的友好的&#xff0c;而且返回内容相对来说&#xff0c;正确率更高的&#xff0c;并且相关场景插件比较丰富的国内厂商。 本文说的&#xff0c;是我自己觉得的&#xff0c;比较有主观…

蓝桥杯-排序

数组排序 Arrays.sort(int[] a) 这种形式是对一个数组的所有元素进行排序&#xff0c;并且时按从小到大的顺序。 package Work;import java.util.*;public class Imcomplete {public static void main(String args[]) {int arr[]new int [] {1,324,4,5,7,2};Arrays.sort(arr)…

第一次捡垃圾

配置 cpu e3 1225 v6 淘宝 130 显卡 p106-100(1060矿卡的特称) 咸鱼 118 内存 8g 3200频率 2 咸鱼 702140 硬盘 128g 固态 咸鱼 35 主板 ex-b150m-v3 咸鱼 110 电源 400w 咸鱼 58 4热管cpu散热器 咸鱼 28 机箱 迷你 拼多多 28 电源线 1m5 淘宝 8 pcie转m.2 拼多多 9 编程器 用…

NineData与OceanBase完成产品兼容认证,共筑企业级数据库新生态

近日&#xff0c;云原生智能数据管理平台 NineData 和北京奥星贝斯科技有限公司的 OceanBase 数据库完成产品兼容互认证。经过严格的联合测试&#xff0c;双方软件完全相互兼容、功能完善、整体运行稳定且性能表现优异。 此次 NineData 与 OceanBase 完成产品兼容认证&#xf…

搜维尔科技:3D Systems Geomagic Design X 逆向工程软件

产品概述 3D Systems Geomagic Design X 是全面的逆向工程软件 GeomagicoDesign XTM是全面的逆向工程软件&#xff0c;它结合了基于特征的CAD数模与三维扫描数据处理&#xff0c;使您能创建出可编辑、基于特征的CAD数模&#xff0c;并与您现有的CAD软件兼容。 拓展您的设计能…

ElasticSearch开篇

1.ElasticSearch简介 1.1 ElasticSearch&#xff08;简称ES&#xff09; Elasticsearch是用Java开发并且是当前最流行的开源的企业级搜索引擎。能够达到实时搜索&#xff0c;稳定&#xff0c;可靠&#xff0c;快速&#xff0c;安装使用方便。 1.2 ElasticSearch与Lucene的关…

【Linux】权限管理(文件的访问者、类型和访问权限,chmod、chown、chgrp、umask,粘滞位)

目录 00.前言 01.文件访问者的分类 02.文件类型和访问权限 文件类型&#xff1a; 文件基本权限&#xff1a; 03.文件权限值的表示方法 04.访问权限的设置 &#xff08;1&#xff09;chmod &#xff08;2&#xff09;chown &#xff08;3&#xff09;chgrp &#xff0…

实战:循环神经网络与文本内容情感分类

在传统的神经网络模型中&#xff0c;是从输入层到隐含层再到输出层&#xff0c;层与层之间是全连接的&#xff0c;每层之间的节点是无连接的。但是这种普通的神经网络对于很多问题却无能为力。例如&#xff0c;你要预测句子的下一个单词是什么&#xff0c;一般需要用到前面的单…

微服务基础

目录 一、单体架构 二、分布式架构 三、微服务 四、微服务结构 五、SpringCloud 六、服务拆分 七、远程调用 一、单体架构 单体架构就是将业务的所有功能都集中在一个项目中进行开发&#xff0c;并打成一个包进行部署。 他的优点很明显&#xff0c;就是架构简单&#xff…

在分布式环境中使用状态机支持数据的一致性

简介 在本文中&#xff0c;我们将介绍如何在分布式系统中使用transaction以及分布式系统中transaction的局限性。然后我们通过一个具体的例子&#xff0c;介绍了一种通过设计状态机来避免使用transaction的方法。 什么是数据库transaction Transaction是关系型数据普遍支持的…

【HarmonyOS】鸿蒙开发之Stage模型-UIAbility的启动模式——第4.4章

UIAbility的启动模式简介 一共有四种:singleton,standard,specified,multion。在项目目录的:src/main/module.json5。默认开启模式为singleton(单例模式)。如下图 singleton&#xff08;单实例模式&#xff09;启动模式 每个UIAbility只存在唯一实例。任务列表中只会存在一…

动态内存经典笔试题分析

题目1&#xff1a; void GetMemory(char *p) { *p (char *)malloc(100); } void Test(void) { char *str NULL; GetMemory(str); strcpy(str, "hello world"); 对NULL指针解引用操作符程序崩溃。 printf(str); } 请问运行Test函数会有什么样的后果&#xff1f; G…

温室气体排放控制中的DNDC模型建模技术及双碳应用

由于全球变暖、大气中温室气体浓度逐年增加等问题的出现&#xff0c;“双碳”行动特别是碳中和已经在世界范围形成广泛影响。国家领导人在多次重要会议上讲到&#xff0c;要把“双碳”纳入经济社会发展和生态文明建设整体布局。同时&#xff0c;提到要把减污降碳协同增效作为促…