当前位置: 首页 > news >正文

字符函数和字符串函数【下篇】

文章目录

  • 🎖️1.函数介绍
    • 📬1.8. strstr
    • 📬1.9. strtok
    • 📬1.10. strerror
    • 📬1.11. memcpy
    • 📬1.12. memmove
    • 📬1.13. memcmp
    • 📬1.14. memset

在这里插入图片描述

🎖️1.函数介绍

📬1.8. strstr

🚩(1)在字符串str1中找字符串str2第一次出现的位置,如果找不到则返回一个空指针(NULL)

可以参考一下 cplusplus 中的资料👇
在这里插入图片描述

🔴(1)请看示例代码👇

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

在这里插入图片描述

🔴(2)模拟实现 strstr函数👇

#include<stdio.h>
#include<string.h>char* my_strstr(const char* str1, const char* 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[] = "abcdbcdef";char arr2[] = "bcd";char* p = my_strstr(arr1, arr2);if (p == NULL){printf("找不到\n");}else{printf("%s\n", p);}return 0;
}

📬1.9. strtok

🔴函数原型👇
char* strtok(char* str, const char* sep);

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

可以参考一下 cplusplus 中的资料👇
在这里插入图片描述

🔴(1)请看示例代码👇

//"shujujiegou@yeah.net"
//@. - 分割符#include<stdio.h>
#include<string.h>int main()
{char arr[] = "shujujiegou@yeah.net";char buf[30] = {0};strcpy(buf, arr);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;
}

在这里插入图片描述

这个代码看起来十分的别扭,非常死板,如果是分三个串就要写三份代码,要是四个串就要写四份代码,如果要分一百个串呢,难不成要写一百份代码吗?

所以我们可以换一种巧妙的方式去写👇

#include<stdio.h>
#include<string.h>int main()
{char arr[] = "192.163.3.122";char buf[30] = { 0 };strcpy(buf, arr);const char* p = ".";char* str = NULL;for (str = strtok(buf, p); str != NULL;str=strtok(NULL,p)){printf("%s\n", str);}return 0;
}

在这里插入图片描述

📬1.10. strerror

🔴函数原型👇
char* strerror(int errnum);
🔴返回错误码所对应的错误信息

可以参考一下 cplusplus 中的资料👇
在这里插入图片描述

🔴(1)请看示例代码👇

int main()
{char* p = strerror(0);printf("%s\n", p);p = strerror(1);printf("%s\n", p);p = strerror(2);printf("%s\n", p);p = strerror(3);printf("%s\n", p);return 0;
}

在这里插入图片描述

🚩 C语言的库函数在调用失败的时候,会将一个错误码存放在一个叫:errno的变量中,当我们想知道调用库函数的时候发生了错误信息,就可以将:errno中的错误码翻译成错误信息

🌰再举个栗子👇

请看代码和注释👇

int main()
{//打开文件//打开文件的时候,如果文件的打开方式是"r"//文件存在则打开成功,文件不存在则打开失败//打开文件失败的话,会返回NULLfopen("test.txt", "r");//"r"已读方式打开FILE* pf = fopen("test.txt", "r");if (pf == NULL){printf("打开文件失败,原因是:%s\n", strerror(errno));}//读写文件//...//关闭文件fclose(pf);pf - NULL;return 0;
}

更高级一点的,如果想直接打印出错误信息,可以使用 perror👇

int main()
{fopen("test.txt", "r");//"r"已读方式打开FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("打开文件失败");return 1;}fclose(pf);pf - NULL;return 0;
}

在这里插入图片描述

📬1.11. memcpy

🔴拷贝数据
🔴上面的 strcpy函数是用来拷贝字符串的

参考一下 cplusplus 中的资料👇
在这里插入图片描述
🚨注意:这里 size_t num参数的单位是字节

🔴(1)请看示例代码与注释👇

void test1()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[8] = { 0 };//把arr1中的前5个数据拷贝到arr2中memcpy(arr2, arr1, 20);
}

🔴(2)请看示例代码与注释👇

void test2()
{float arr1[] = { 1.0f,2.0f,3.0f,4.0f,5.0f };float arr2[8] = { 0 };//把arr1中的前3个数据拷贝到arr2中memcpy(arr2, arr1, 12);
}

🔴(3)模拟实现一下 memcpy函数👇

//memcpy函数返回的是目标空间的起始地址
void* my_memcpy(void* dest, const void* src, size_t num)
{void* ret = dest;assert(dest && src);while (num--)//4 3 2 1{*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}void test3()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[8] = { 0 };//把arr1中的前5个数据拷贝到arr2中my_memcpy(arr2, arr1, 20);
}int main()
{test3();return 0;
}

🔴(4)请看示例代码与注释👇
把前五个数据放在3 4 5 6 7的位置上

void* my_memcpy(void* dest, const void* src, size_t num)
{void* ret = dest;assert(dest && src);while (num--)//4 3 2 1{*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}void test4()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//把前五个数据放在3 4 5 6 7的位置上my_memcpy(arr1+2, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}
}int main()
{test4();return 0;
}

在这里插入图片描述
🚨结果为什么不是我们期望的结果呢?怎么出问题了呢?

在这里插入图片描述
这里把1和2赋给3和4之后,3和4的位置的值已经被改变了,分别变成了1和2,那么再3和4赋给5和6位置的时候,赋的就是1和2,所以才会这样

所以我们发现:在内存重叠的时候,使用 memcpy可能出现意想不到的效果
建议:在内存重叠的情况,使用 memmove函数

📬1.12. memmove

先来参考一下 cplusplus 中的资料👇
在这里插入图片描述

🔴请看示例代码👇

void test4()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//把前五个数据放在3 4 5 6 7的位置上memmove(arr1 + 2, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}
}int main()
{test4();return 0;
}

在这里插入图片描述
这次就成功完成了

🚩memcpy拷贝不重叠的内存
🚩重叠的就交给 memmore
🚩memmore > memcpy

📬1.13. memcmp

🔴内存比较函数(以字节为单位)

先来参考一下 cplusplus 中的资料👇
在这里插入图片描述

🔴请看示例代码👇

void test5()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 1,2,3,4,6 };int ret = memcmp(arr1, arr2, 16);printf("%d\n", ret);
}int main()
{test5();return 0;
}

在这里插入图片描述

void test5()
{int arr1[] = { 1,2,3,4,5 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00int arr2[] = { 1,2,3,4,6 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 06 00 00 00int ret = memcmp(arr1, arr2, 17);printf("%d\n", ret);
}int main()
{test5();return 0;
}

在这里插入图片描述

📬1.14. memset

🔴内存设置函数(以字节为单位设置)

先来参考一下 cplusplus 中的资料👇
在这里插入图片描述

🔴请看示例代码👇

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

在这里插入图片描述

总结🥰
以上就是 字符函数和字符串函数【下篇】 的内容啦🥳🥳🥳🥳
本文章所在【C语言知识篇】专栏,感兴趣的烙铁可以订阅本专栏哦🥳🥳🥳
希望我们可以做一个用心的人💕💕💕
小的会继续学习,继续努力带来更好的作品😊😊😊
创作写文不易,还多请各位大佬uu们多多支持哦🥰🥰🥰

请添加图片描述

相关文章:

字符函数和字符串函数【下篇】

文章目录&#x1f396;️1.函数介绍&#x1f4ec;1.8. strstr&#x1f4ec;1.9. strtok&#x1f4ec;1.10. strerror&#x1f4ec;1.11. memcpy&#x1f4ec;1.12. memmove&#x1f4ec;1.13. memcmp&#x1f4ec;1.14. memset&#x1f396;️1.函数介绍 &#x1f4ec;1.8. st…...

【CSS】盒子模型内边距 ② ( 内边距复合写法 | 代码示例 )

文章目录一、内边距复合写法1、语法2、代码示例 - 设置 1 个值3、代码示例 - 设置 2 个值4、代码示例 - 设置 3 个值5、代码示例 - 设置 4 个值一、内边距复合写法 1、语法 盒子模型内边距 可以通过 padding-left 左内边距padding-right 右内边距padding-top 上内边距padding-…...

uni-app ——使用uploadFile上传多张图片

前言&#xff1a;最近的工作中出现了一个功能点&#xff0c;具体写法我在前面的文章中已经阐述过&#xff0c;不过之前的情况是上传图片调用后端的一个接口&#xff0c;整个表单页面提交的时候调用的是另一个接口&#xff0c;我也从中学到了另外的一种方法&#xff0c;写到这里…...

Linux - 进程控制(进程等待)

进程等待必要性之前讲过&#xff0c;子进程退出&#xff0c;父进程如果不管不顾&#xff0c;就可能造成‘僵尸进程’的问题&#xff0c;进而造成内存泄漏。另外&#xff0c;进程一旦变成僵尸状态&#xff0c;那就刀枪不入&#xff0c;“杀人不眨眼”的kill -9 也无能为力&#…...

Python 可视化最频繁使用的10大工具

今天介绍Python当中十大可视化工具&#xff0c;每一个都独具特色&#xff0c;惊艳一方。 文章目录Matplotlib技术提升SeabornPlotlyBokehAltairggplotHoloviewsPlotnineWordcloudNetworkxMatplotlib Matplotlib 是 Python 的一个绘图库&#xff0c;可以绘制出高质量的折线图、…...

Windows与Linux端口占用、查看的方法总结

Windows与Linux端口占用、查看的方法总结 文章目录Windows与Linux端口占用、查看的方法总结一、Windows1.1Windows查看所有的端口1.2查询指定的端口占用1.3查询PID对应的进程1.4查杀死/结束/终止进程二、Linux2.1lsof命令2.2netstat命令一、Windows 1.1Windows查看所有的端口 …...

48天强训 Day1 JavaOj

48天强训 & Day1 & JavaOj 1. 编程题1 - 组队竞赛 组队竞赛_牛客笔试题_牛客网 (nowcoder.com) 1.1 读题 1.2 算法思想基础 我们应该尽量的让每一个队伍的中间值都最大化~我们应该尽量的让每一个队伍的最小值都足够小~前33%的不应该都作为每个队伍的最大值~ 接下来…...

崩溃的一瞬间

——我可以忍受黑暗&#xff0c;除非我从未见过光明 原来&#xff0c;人真的会崩溃&#xff0c;如果不是昨夜的眼泪&#xff0c;我到现在还不知道人为什么会在一瞬间崩溃。 刚和认识不久的女孩子聊完天准备入睡。忽然想到自己可能过几个月就要离开这座待了仅一年多的城市…...

13回归网络:HTTP/2是怎样的网络协议?

本篇文章我们先放下实践,回归网络,深入gRPC底层的HTTP/2协议,去探究一下框架底层网络协议的原理,提升对高性能网络协议的认知,相信读完这篇文章以后,我们就可以了解HTTP/2有哪些优势,为什么gRPC要使用HTTP/2作为底层的传输协议。 在众多研究HTTP/2的博客和资料中,最具…...

CSS学习笔记——基础选择器,字体属性,文本属性,三种样式表

文章目录基础选择器标签选择器类选择器多类名使用方式id选择器通配符选择器字体属性字体系列字体字号字体粗细文字样式复合属性文本属性文本颜色对齐文本装饰文本文本缩进行间距CSS的三种样式表行内样式表&#xff08;行内式&#xff09;内部样式表&#xff08;嵌入式&#xff…...

第十四届蓝桥杯三月真题刷题训练——第 16 天

目录 第 1 题&#xff1a;英文字母 问题描述 输入格式 输出格式 样例输入 1 样例输出 1 样例输入 2 样例输出 2 评测用例规模与约定 运行限制 代码&#xff1a; 第 2 题&#xff1a;单词分析 题目描述 输入描述 输出描述 输入输出样例 运行限制 数组代码&…...

鸟哥的Linux私房菜 Shell脚本

第十二章、学习 Shell Scripts https://linux.vbird.org/linux_basic/centos7/0340bashshell-scripts.php 12.2 简单的 shell script 练习 #!/bin/bash# Program: # User inputs his first name and last name. Program shows his full name.read -p "Please in…...

FPGA基于RIFFA实现PCIE采集ov5640图像传输,提供工程源码和QT上位机

目录1、前言2、RIFFA理论基础3、设计思路和架构4、vivado工程详解5、上板调试验证并演示6、福利&#xff1a;工程代码的获取1、前言 PCIE是目前速率很高的外部板卡与CPU通信的方案之一&#xff0c;广泛应用于电脑主板与外部板卡的通讯&#xff0c;PCIE协议极其复杂&#xff0c…...

week13周报

一.动态规划走楼梯2难点&#xff1a;不能连续走三次两级台阶如何表示思路&#xff1a;可以用二维数组f[i][j],i表示当前台阶数&#xff0c;j表示已经连续走了j次二级台阶了转移方程&#xff1a;f[i2][j1]f[i2][j1]f[i][j] 当j&#xff01;2时&#xff0c;我们可以选择走二级台阶…...

离散选择模型中的分散系数theta到底该放在哪里呢?

前言 \quad~~一直都在想为啥子离散选择模型中分散系数以分母形式出现而在路径选择公式中以系数形式出现呢&#xff1f;看着公式想了想&#xff0c;现在想出了一个似乎感觉应该差不多很合理的答案&#xff0c;希望与大家一起探讨。 进入正题 根据随机效用理论&#xff0c;决策…...

【CSAPP】进程 | 上下文切换 | 用户视角下的并发进程

&#x1f4ad; 写在前面&#xff1a;本文将学习《深入理解计算机系统》的第六章 - 关于异常控制流和系统级 I/O 的 进程部分。CSAPP 是计算机科学经典教材《Computer Systems: A Programmers Perspective》的缩写&#xff0c;该教材由Randal E. Bryant和David R. OHallaron 合著…...

节流还在用JS吗?CSS也可以实现哦

函数节流是一个我们在项目开发中常用的优化手段&#xff0c;可以有效避免函数过于频繁的执行。一般函数节流用在scroll页面滚动&#xff0c;鼠标移动等。 为什么需要节流呢&#xff0c;因为触发一次事件就会执行一次事件&#xff0c;这样就形成了大量操作dom,会出现卡顿的情况…...

带你看看 TypeScript 5.0 的新特性

一、写在前面 TypeScript 5.0 已经于 2023 年 3 月 16 日发布了&#xff0c;带来了许多新功能&#xff0c;同时也在性能方面进行了优化&#xff0c;下面让我们来一起看看新版 TypeScript 中比较有重要的变化吧。 二、新特性 2-1、速度、包体积优化 首先是新版本性能的提升&…...

C语言预处理条件语句的 与或运算

C语言预处理条件语句的 与或运算 1.#ifdef 与或运算 #ifdef (MIN) && (MAX) ----------------------------错误使用 #if defined(MIN) && defined(MAX) ---------------- 正确使用 #ifdef (MIN) || (MAX) -----------------------------错误使用 …...

从零实现深度学习框架——学习率调整策略介绍

引言 本着“凡我不能创造的,我就不能理解”的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导。 要深入理解深度学习,从零开始创建的经验非常重要,从自己可以理解的角度出发,尽量不使用外部完备的框架前提下,实现我…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...