零基础教学必会篇(详解字符函数和字符串函数)(完结版)

news/2024/5/5 2:26:44/文章来源:https://blog.csdn.net/qq_65662221/article/details/130024384

各位csdn的友友们好,上次阿博给大家讲了一些简单的字符串函数的功能和模拟实现,今天就和阿博一起再上一个台阶继续拿捏它们😊😊😊

在这里插入图片描述

文章目录

    • 1.strstr的功能介绍
    • 2.strstr函数的模拟实现
    • 3.strtok的功能介绍
    • 4.strerror和perror的功能介绍
    • 5.memcpy的功能介绍
    • 6.memcpy函数的模拟实现
    • 7.内存重叠
    • 8.memmove的功能介绍
    • 9.memmove函数的模拟实现
    • 10.memcmp的功能介绍
    • 11.memcmp函数的模拟实现
    • 12.memset的功能介绍

1.strstr的功能介绍

2.strstr函数的模拟实现

3.strtok的功能介绍

4.strerror和perror的功能介绍

5.memcpy的功能介绍

6.memcpy函数的模拟实现

7.内存重叠

8.memmove的功能介绍

9.memmove函数的模拟实现

10.memcmp的功能介绍

11.memcmp函数的模拟实现

12.memset的功能介绍

1.strstr的功能介绍
在这里插入图片描述

它的功能就是在str1中找str2,而且是第一次出现的位置,如果没有找到,则返回的是空指针,如果找到了str2,并且找到多次,它只返回第一次出现的地址

代码测试

#include<stdio.h>
#include<string.h>
int  main()
{char arr1[] = "abcdebcdf";char arr2[] = "bcd";//char arr2[]="bcq";char*p= strstr(arr1, arr2);if (p == NULL){printf("找不到\n");}elseprintf("%s\n", p);return  0;
}

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

这就是strstr相关的功能了,如果找到了,友友们一定要切记返回的是第一次出现的地址.

这里阿博再给友友们拓展一些相类似的函数
1.strchr
在这里插入图片描述

这个函数的功能是在一个字符串中找字符第一次出现的位置.

2.strrchr
在这里插入图片描述

这个函数的功能是找一个字符在字符串中最后一次出现的位置.

2.strstr函数的模拟实现

逻辑分析
在这里插入图片描述
代码实现

 #include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);char* s1 = NULL;char* s2 = NULL;char* cp = (char*)str1;while (*cp){s1 = cp;s2 = (char*)str2;while (*s1 && *s2 && *s1 == *s2){s1++;s2++;}if (*s2 == '\0'){return  cp;}cp++;}return  NULL;
}
int  main()
{char arr1[] = "abcdebcdf";//char arr2[] = "bcd";char arr2[]="bcd";char*p= my_strstr(arr1, arr2);if (p == NULL){printf("找不到\n");}elseprintf("%s\n", p);return  0;
}

3.strtok的功能介绍
在这里插入图片描述
这里阿博给友友们传输一些内功🥷🥷🥷

1.delimiters参数是个字符串,定义了用作分隔符的字符集合
2.第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记.
3.strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改
4.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置.
5.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。如果字符串中不存在更多的标记,则返回 NULL 指针.

代码测试1

//strtok的功能介绍
int main()
{char arr[] = "i@love.you";char buf[30] = { 0 };strcpy(buf, arr);        //这里是在buf文件里面操作,防止原文件被改变const char* p = "@.";char*str=strtok(buf, p);printf("%s\n", str);str = strtok(NULL, p);printf("%s\n", str);str = strtok(NULL, p);printf("%s\n", str);return  0;
}

在这里插入图片描述

这种写法没有错,但是如果分隔符比较多的话,我们需要写很多行代码,所以我们换一种方法.

在这里插入图片描述
代码测试2

int main()
{char arr[] = "i@love.you";char buf[30] = { 0 };strcpy(buf, arr);        //这里是在buf文件里面操作,防止原文件被改变const char* p = "@.";char* str = NULL;for (str = strtok(buf, p); str != NULL; str = strtok(NULL, p))  //第一次我们传buf的地址,然后第二次,第三次,第四次......我们都传空指针的地址,到最后没有分割符了,str为空,跳出循环.{printf("%s\n", str);}return  0;
}

在这里插入图片描述
4.strerror和perror的功能介绍
strerror
在这里插入图片描述
代码测试

int  main()
{FILE* pf = fopen("text.txt", "r");if (pf == NULL){printf("打开文件失败,原因是:%s\n", strerror(errno));return 1;}fclose(pf);pf = NULL;return  0;
}

在这里插入图片描述

这里阿博给友友们解答一下疑惑,其实c语言的库函数在调用失败的时候,会将一个错误码存放在一个叫:errno的变量中,当我们想知道调用库函数的时候产生了什么错误信息,就可以将errno中的错误码翻译成错误信息.

在这里插入图片描述

友友们注意,我们一定要把这个文件扩展名给打开,这样我们就可以完整的看到文件名了.

perror
在这里插入图片描述
代码测试

int  main()
{FILE* pf = fopen("text.txt", "r");if (pf == NULL){perror("打开文件失败");   //其实就可以把perror抽象的理解成printf+serrorreturn 1;}fclose(pf);pf = NULL;return  0;
}

在这里插入图片描述
5.memcpy的功能介绍
在这里插入图片描述
代码测试

void test1()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[10] = { 0 };memcpy(arr2, arr1, 20);       //注意这里是字节个数,不是元素个数int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr2[i]);}
}
void test2()
{float arr1[] = { 1.0f,2.0f,3.0f,4.0f,5.0f };float arr2[10] = { 0 };memcpy(arr2, arr1, 12);int i = 0;for (i = 0; i < 10; i++)      //注意这里是字节个数{printf("%f ", arr2[i]);}
}
int  main()
{//test1();test2();return  0;
}

在这里插入图片描述

在这里插入图片描述
6.memcpy函数的模拟实现

代码实现

#include<assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{assert(dest && src);void* ret = dest;while (num--){//*dest = *src;//dest++;//src++;           //err*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}
void test1()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[10] = { 0 };my_memcpy(arr2, arr1, 20);       //注意这里是字节个数,不是元素个数int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr2[i]);}
}

🕹️🕹️🕹️友友们注意虽然void*的指针可以接收任意类型的数据,但是这种指针不能直接解引用和加减运算.🕹️🕹️🕹️

7.内存重叠

代码测试


#include<assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{assert(dest && src);void* ret = dest;while (num--){//*dest = *src;//dest++;//src++;           //err*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}
void test1()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };// 1,2,1,2,3,4,5,8,9,10   我们期待的结果my_memcpy(arr1+2, arr1, 20);       //注意这里是字节个数,不是元素个数int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}
}

在这里插入图片描述

8.memmove的功能介绍
在这里插入图片描述
代码测试

void test1()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };// 1,2,1,2,3,4,5,8,9,10   我们期待的结果memmove(arr1+2, arr1, 20);       //注意这里是字节个数,不是元素个数int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}
}

在这里插入图片描述
9.memmove函数的模拟实现

逻辑分析
在这里插入图片描述

代码实现

#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--){//*dest = *src;//dest++;//src++;           //err*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else{while (num--){*((char*)dest + num) = *((char*)src + num);   //这里的num已经是19了}}return ret;
}

在这里插入图片描述
10.memcmp的功能介绍
在这里插入图片描述
代码测试

void test3()
{int arr1[] = { 1,2,3,4,7 };int arr2[] = { 1,2,3,4,6 };int ret = memcmp(arr1, arr2, 17);printf("%d\n", ret);
}

11.memcmp函数的模拟实现

代码实现

#include<assert.h>
int my_memcmp(const void* str1, const void* str2,size_t num)
{assert(str1 && str2);while (num--){if(*(char*)str1!=*(char*)str2)return  *(char*)str1 - *(char*)str2;str1 = (char*)str1 + 1;str2 = (char*)str2 + 1;}return 0;
}
void test3()
{int arr1[] = { 1,2,3,4,7 };int arr2[] = { 1,2,3,4,6 };int ret = my_memcmp(arr1, arr2, 16);printf("%d\n", ret);
}
int  main()
{//test1();//test2();test3();return  0;
}

12.memset的功能介绍
在这里插入图片描述
代码实现

void  test4()
{char arr[] = "hello world";memset(arr, 'x', 5);printf("%s\n", arr);
}

在这里插入图片描述

友友们注意memset是以字节为单位设置的

错误示范

void test5()
{int arr[10] = { 0 };memset(arr, 1, sizeof(arr));      // 01  01  01  01,这种写法无法将每个元素设置为1int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr[i]);}
}

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

好了友友们,本期创作到这里就告一段落了,如果感觉有帮助的话,可以给阿博点个关注哦,后续会继续给友友们带来一些新的干货😊😊😊

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

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

相关文章

零基础学习Java 06

目录 String String构造方法 字符串查找 字符串截取 字符串替换 字符串拆分 字符串修改 String String类在java.lang包下&#xff0c;所以使用的时候不需要导包。 String构造方法 字符串查找 char charAt(int index)&#xff0c;输入位置index&#xff0c;找单个字符 …

MAE论文笔记+Pytroch实现

Masked Autoencoders Are Scalable Vision Learners&#xff0c; 2021 近期在梳理Transformer在CV领域的相关论文&#xff0c;落脚点在于如何去使用Pytroch实现如ViT和MAE等。通过阅读源码&#xff0c;发现不少论文的源码都直接调用timm来实现ViT。故在此需要简单介绍一下timm…

Linux 中的 /dev/random 和 /dev/urandom 是什么?

在Linux系统中&#xff0c;/dev/random和/dev/urandom是两个特殊的设备文件&#xff0c;用于生成随机数。在本文中&#xff0c;我们将深入探讨这两个设备文件的区别&#xff0c;以及它们在Linux系统中的作用。 /dev/random /dev/random是一个随机数生成器设备文件&#xff0c;…

windows10下编译zlib库

系列文章目录 文章目录系列文章目录前言一、问题原因二、准备具体操作编译zlib工程前言 我使用CMake编译zlib源码&#xff0c;出现警告&#xff1a;CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required): Compatibility with CMake < 2.8.12 will be r…

五、基础初始化(init_sequence)

初始化序列数组 # < lib_arm\board.c > init_fnc_t *init_sequence[] { board_init, /* basic board dependent setup */ timer_init, /* initialize timer */ env_init, /* initialize environment */ init_baudrate, /* initialze baudrate settings */ serial_…

VUE3 学习笔记(七)动态样式 class 实现

目录 一、绑定 HTML class 1. 绑定对象 2. 绑定数组 3. 在组件上使用 二、绑定内联样式 1. 绑定对象 2. 绑定数组 3. 自动前缀 4. 样式多值 数据绑定的一个常见需求场景是操纵元素的 CSS class 列表和内联样式。因为 class 和 style 都是 attribute&#xff0c;我们可…

一道小学题,解答了我与学霸的差距

目录一、背景二、题目三、过程1.形式转换2.个位数相加只能向前进一位嘛&#xff1f;进两位可以吗&#xff1f;进三位呢&#xff1f;3.十位数上要填写的内容&#xff0c;可以是0嘛&#xff1f;你想到了吗&#xff1f;4.如何下意识的去做结构化&#xff1f;四、总结五、升华一、背…

讲一下dns过程:给一个网址www.google.com,dns服务器如何逐级解析的?

DNS 中的域名都是用句点来分隔的&#xff0c;比如 www.server.com&#xff0c;这里的句点代表了不同层次之间的界限。在域名中&#xff0c;越靠右的位置表示其层级越高。域名最后还有一个点&#xff0c;比如 www.server.com.&#xff0c;这个最后的一个点代表根域名。 根DNS服…

UDP套接字

大家好,又见面了,&#x1f389;&#x1f389;&#x1f389;&#x1f338;&#x1f338;&#x1f338; 今天为大家带来UDP套接字的相关知识 文章目录认识socketUDP和TCP认识UDPAPI有关方法基于UDP实现回显服务器UDP的方法基于UDP实现回显程序认识socket UDP和TCP 认识UDPAPI有…

腾讯空降测试工程师,绩效次次拿S,真是砂纸擦屁股,给我露了一手啊

​上周我们公司的绩效面谈全部结束了&#xff0c;每年到这个时间点就是打绩效的时候了&#xff0c;对于职场打工人来说绩效绝对是最重要的事情之一&#xff0c;原因也很简单&#xff1a;奖金、晋升、涨薪都和它有关系。 比如下面这个美团员工在脉脉上的自曝就很凄凉&#xff1…

多种方法解决VS在创建多个源文件后运行时出现的重定义错误:main已经在1.obj中定义

名人说&#xff1a;博学之&#xff0c;审问之&#xff0c;慎思之&#xff0c;明辨之&#xff0c;笃行之。——《中庸》 创作者&#xff1a;Code_流苏(CSDN) 本篇文章收录于&#xff1a;各类问题记录专栏 记录一、原因经过二、解决方法1️⃣方法一 注释2️⃣方法二 生成排除3️⃣…

学习Python的一些知识点记录

一、对象比较 Python中有两种对象比较方式&#xff1a; 值比较。使用比较符号&#xff08;、>、<等&#xff09;标识符比较。使用 is、not 关键字。标识符就是对象在内存中的有效地址&#xff0c;使用 id() 函数可以得到对象的标识符。二、None 对象 这是一个特殊对象…

【Python】数学 - 用 Python 自动化求解函数 f(x) 的值

目录 1、缘起 2、求以下函数的值 3、代码清单 3.1、求解 f(0)、f(1)、 f(​编辑)、f(​编辑) 3.2、求解 g(0)、g(1)、g(​编辑)、g(​编辑) 3.3、求解 h(0)、h(1)、h(​编辑)、h(​编辑) 4、总结 1、缘起 Python 是一种强大的编程语言&#xff0c;它具有广泛的应用领域。…

四、第二阶段

全局数据 声明 # < lib_arm\board.c > DECLARE_GLOBAL_DATA_PTR; 定义 # < include\asm\global_data.h > typedef struct global_data { bd_t *bd; unsigned long flags; unsigned long baudrate; unsigned long have_console; /* serial_init() was calle…

使用adb 命令删除手机预装app

1. 手机开启开发者选项&#xff0c;允许usb调试&#xff1b; 2.pc 安装adb&#xff0c; 1&#xff09;Windows版本&#xff1a;https://dl.google.com/android/repository/platform-tools-latest-windows.zip 2&#xff09;按键windowsr打开运行&#xff0c;输入sysdm.cpl&a…

Go 语言安装部署,两分钟让你写`上Hello World`(包含 goland 开发工具)

Go 语言安装部署&#xff0c;两分钟让你写上Hello World&#xff08;包含 goland 开发工具&#xff09; 第一步下载 Go 安装包 官网 https://golang.google.cn/dl/ 根据自己使用电脑平台选择安装版本 第二步 安装 GO 打开安装包直接点击next下一步 勾选协议&#xff0c;继…

10 kafka生产者发送消息的原理

1.发送原理&#xff1a; 在消息发送的过程中&#xff0c;涉及到了两个线程——main 线程和 Sender 线程。在 main 线程 中创建了一个双端队列 RecordAccumulator。main 线程将消息发送给 RecordAccumulator&#xff0c; Sender 线程不断从 RecordAccumulator 中拉取消息发送到…

CTFHub | 00截断

0x00 前言 CTFHub 专注网络安全、信息安全、白帽子技术的在线学习&#xff0c;实训平台。提供优质的赛事及学习服务&#xff0c;拥有完善的题目环境及配套 writeup &#xff0c;降低 CTF 学习入门门槛&#xff0c;快速帮助选手成长&#xff0c;跟随主流比赛潮流。 0x01 题目描述…

IDEA修改主题 设置背景图片

IDEA修改主题 设置背景图片 目录IDEA修改主题 设置背景图片1.修改IDEA默认主题2.修改IDEA背景图片2.1 打开设置界面2.2 下载插件很多小白在刚刚使用IDEA的时候还不是很熟练本文主要给大家提供一些使用的小技巧&#xff0c;希望能帮助到你1.修改IDEA默认主题 IDEA的默认主题是黑…

Jmeter 工具测试 websocket

WebSocket 是一种基于在单个 TCP 连接上进行全双工通信的协议&#xff0c;是从HTML5开始提供的一种浏览器与服务器之间进行全双工通讯的网络技术。相较于 HTTP 协议&#xff0c;WebSocket 协议实现了持久化网络通信&#xff0c;可以实现客户端和服务端的长连接&#xff0c;能够…