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

字符函数和字符串函数(下)——“C”

各位CSDN的uu们你们好呀,今天小雅兰的内容依旧是字符函数和字符串函数呀,这篇博客会讲一些内存相关的函数,下面,让我们进入字符函数和字符串函数的世界吧


字符串查找

        strstr

        strtok

错误信息报告

        strerror

字符操作

内存操作函数

        memcpy

        memmove

        memset

        memcmp


 strstr

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

Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.

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

 模拟实现strstr

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

strtok

                char * strtok ( char * str, const char * sep );  

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

使用strtok这个函数

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{char arr[] = "xiaoyalan@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;
}

当然,这个代码写得不是很好,如果是有很多分隔符呢,岂不是要写很多个printf,这样,代码冗余的问题就会非常严重,那么,必然就要用到循环啦,下面,我们来改进一下这个代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{char* p = "xiaoyalan@yeah.net";const char* sep = ".@";char arr[30];char* str = NULL;strcpy(arr, p);//将数据拷贝一份,处理arr数组的内容for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep)){printf("%s\n", str);}return 0;
}

strerror

                char * strerror ( int errnum );  

返回错误码,所对应的错误信息。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
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);p = strerror(4);printf("%s\n", p);p = strerror(5);printf("%s\n", p);p = strerror(6);printf("%s\n", p);return 0;
}

#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{//打开文件//打开文件的方式,如果文件的打开方式是“r”//文件存在则打开成功,文件不存在则打开失败//打开文件夹失败的话,会返回NULLFILE* pf = fopen("test.txt", "r");if (pf == NULL){printf("打开文件失败,原因是:%s\n", strerror(errno));return 1;}//读写文件//......//关闭文件fclose(pf);pf = NULL;return 0;
}

 

另一种写法:

#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{//打开文件//打开文件的方式,如果文件的打开方式是“r”//文件存在则打开成功,文件不存在则打开失败//打开文件夹失败的话,会返回NULLFILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("打开文件失败");return 1;}//读写文件//......//关闭文件fclose(pf);pf = NULL;return 0;
}

 

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


字符分类函数 

字符转换 

int tolower ( int c );
int toupper ( int c );
#include <stdio.h>
#include <ctype.h>
int main()
{int i = 0;char str[] = "Test String.\n";char c;while (str[i]){c = str[i];if (isupper(c))c = tolower(c);putchar(c);i++;}return 0;
}

memcpy

        void * memcpy ( void * destination, const void * source, size_t num );  

  • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
  • 这个函数在遇到 '\0' 的时候并不会停下来。
  • 如果source和destination有任何的重叠,复制的结果都是未定义的。  

使用一下此函数:

#include<stdio.h>
#include<string.h>
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);
}
void test2()
{float arr1[] = { 1.0f,2.0f,3.0f,4.0f,5.0f };float arr2[8] = { 0 };memcpy(arr2, arr1, 20);
}
int main()
{test1();test2();return 0;
}

模拟实现memcpy:

#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{void* ret = dest;assert(dest != NULL);assert(src != NULL);while (num--){*(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;
}
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{void* ret = dest;assert(dest != NULL);assert(src != NULL);while (num--){*(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 };my_memcpy(arr1+2, arr1, 40);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}
}
int main()
{test4();return 0;
}

所以我们发现:在内存重叠的情况下,使用memcpy可能出现意想不到的效果

                在内存重叠的情况下,使用memmove函数


memmove

        void * memmove ( void * destination, const void * source, size_t num );  

  • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
  • 如果源空间和目标空间出现重叠,就得使用memmove函数处理。

模拟实现memmove

 

#include <stdio.h>
#include <string.h>
#include<assert.h>
void* my_memmove(void* dest, const void* src, size_t num)
{void* ret = dest;assert(dest != NULL);assert(src != NULL);if (dest < src){//前->后while (num--){*(char*)dest = *(char*)src;dest = *(char*)dest + 1;src = *(char*)src + 1;}}else{//后->前while (num--){*((char*)dest + num) = *((char*)src + num);}}return ret;
}
void test4()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr1+2, arr1, 40);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}
}
int main()
{test4();return 0;
}

 


memcmp

        int memcmp ( const void * ptr1, const void * ptr2, size_t num );

比较从ptr1和ptr2指针开始的num个字节

 使用memcmp

#include <stdio.h>
#include <string.h>
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;
}

 


memset

 

#include <stdio.h>
#include <string.h>
void test6()
{int arr[10] = { 0 };memset(arr, 1, sizeof(arr));int i = 0;for (i = 0; i < 10; i++){printf("%p\n", arr[i]);//这种写法没办法把每个数组元素设置为1}return 0;
}
int main()
{test6();return 0;
}

 

 


好啦,小雅兰今天的内容就到这里啦,这就是字符串函数基本的内容啦,未来还要继续努力!!!

 

相关文章:

字符函数和字符串函数(下)——“C”

各位CSDN的uu们你们好呀&#xff0c;今天小雅兰的内容依旧是字符函数和字符串函数呀&#xff0c;这篇博客会讲一些内存相关的函数&#xff0c;下面&#xff0c;让我们进入字符函数和字符串函数的世界吧 字符串查找 strstr strtok 错误信息报告 strerror 字符操作 内存操作函…...

kafka docker 安装

先启动起 zookeeper &#xff08;1&#xff09;服务&#xff1a; 192.168.190.35docker run -d --name kafka1 \-p 9092:9092 \-e KAFKA_BROKER_ID0 \-e delete.topic.enabletrue \-e num.partitions1 \-e KAFKA_ZOOKEEPER_CONNECT192.168.192.35:2181 \-e KAFKA_ADVERTISED_LI…...

SpringBean管理

一.什么是SpringBean? 在Spring中将管理对象称为 Bean.Bean是由一个SpringIOC容器实例化,组装和管理的对象.也就是说,Bean并不是由我们程序员编写的,而是在程序运行过程中,由Spring通过反射机制生成的. SpringBean是Spring框架在运行时管理的对象,我们编写的大多数逻辑代码都…...

关于Vue3中reactive的意义

在学习Vue3的时候产生疑问&#xff1a; const addForm reactive({ // 这里面的reactive啥意思sysPre: null,diaPre: null,tem: null })查询解决 在Vue3中&#xff0c;响应式对象是指通过reactive函数转换而来的对象&#xff0c;它的属性可以被Vue自动监测&#xff0c;当属性…...

平衡三进制

平衡三进制 一、定义 平衡三进制&#xff0c;也称为对称三进制。这是一个不太标准的 计数体系。 正规的三进制的数字都是由 0,1,2 构成的&#xff0c;而平衡三进制的数字是由 -1,0,1 构成的。它的基数也是 3&#xff08;因为有三个可能的值&#xff09;。由于将 -1 写成数字…...

python爬取网站数据

开学前接了一个任务&#xff0c;内容是从网上爬取特定属性的数据。正好之前学了python&#xff0c;练练手。 编码问题 因为涉及到中文&#xff0c;所以必然地涉及到了编码的问题&#xff0c;这一次借这个机会算是彻底搞清楚了。 Unicode是一种编码方案&#xff0c;又称万国码…...

CSS的三大特性

&#x1f31f;所属专栏&#xff1a;前端只因变凤凰之路&#x1f414;作者简介&#xff1a;rchjr——五带信管菜只因一枚&#x1f62e;前言&#xff1a;该系列将持续更新前端的相关学习笔记&#xff0c;欢迎和我一样的小白订阅&#xff0c;一起学习共同进步~&#x1f449;文章简…...

Linux-scheduler之负载均衡(二)

四、调度域 SDTL结构 linux内核使用SDTL结构体来组织CPU的层次关系 struct sched_domain_topology_level {sched_domain_mask_f mask; //函数指针&#xff0c;用于指定某个SDTL的cpumask位图sched_domain_flags_f sd_flags; //函数指针&#xff0c;用于指定某个SD…...

VScode第三方插件打开sqlite数据库

文章目录前言对比1.文本文件、表格软件打开2.专业软件3.pythonVScode 第三方库打开数据库1. 下载第三方库插件2.打开sqlite新建查询3.输入查询内容前言 最近在做的东西涉及SQLite数据库&#xff08;一种常用在移动端的数据库类型&#xff0c;和mysql这些主流数据库也差不多&am…...

Kafka 监控

Kafka 监控主机监控JVM 监控集群监控监控 Kafka 客户端主机监控 主机监控 : 监控 Kafka 集群 Broker 所在的节点机器的性能 主机监控指标 : 机器负载 (Load) , CPU 使用率内存使用率 (空闲内存 , 已使用内存 (Used Memory) )磁盘 I/O 使用率 (读使用率/ 写使用率) , 网络 I/…...

MultipartFile与File的互转

MultipartFile与File的互转前言MultipartFile转File1.FileUtils.copyInputStreamToFile转换2.multipartFile.transferTo(tempFile);3. (推荐&#xff09;FileUtils.writeByteArrayToFile(file, multipartFile.getBytes());File转MultipartFile前言 需求是上传Excel文件并读取E…...

数据结构与算法基础-学习-15-二叉树

一、二叉树定义二叉树是N&#xff08;N>0&#xff09;个节点的有限集&#xff0c;它可能是空集或者由一个根节点及两棵互不相交的分别称作这个根的左子树和右子树的二叉树组成。二、二叉树特点1、每个节点最多两个孩子。&#xff08;也就是二叉树的度小于等于2&#xff09;2…...

接口测试要测试什么?

一. 什么是接口测试&#xff1f;为什么要做接口测试&#xff1f; 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及系统间的相互…...

2023.03.12学习总结

项目部分写了内外菜单栏的伸缩&#xff0c;更新了导航栏&#xff0c;新增配置&#xff0c;scss变量 提交记录 学习了scss的使用和配置 &#xff0c;设置了scss全局变量&#xff0c;组件样式 给element-plus配置了主题颜色&#xff0c;配置到了全局 http://t.csdn.cn/FhZYa …...

数据结构入门6-1(图)

目录 注 图的定义 图的基本术语 图的类型定义 图的存储结构 邻接矩阵 1. 邻接矩阵表示法 2. 使用邻接矩阵表示法创建无向网 3. 邻接矩阵表示法的优缺点 邻接表 1. 邻接表表示法 2. 通过邻接表表示法创建无向图 3. 邻接表表示法的优缺点 十字链表&#xff08;有向…...

把C#代码上传到NuGet,大佬竟是我自己!!!

背景 刚发表完一篇博客总结自己写标准化C#代码的心历路程&#xff0c;立马就产生一个问题&#xff0c;就是我写好标准化代码后&#xff0c;一直存放磁盘的话&#xff0c;随着年月增加&#xff0c;代码越来越多&#xff0c;项目和版本的管理就会成为一个令我十分头疼的难题&…...

解决前端“\n”不换行问题

在日常开发过程中&#xff0c;换行显示是一种很常见的应用需求&#xff0c;但是偶然发现&#xff0c;有时候使用 "\n"并不会换行显示&#xff0c;只会被识别为空格&#xff0c;如下图。 通过上图可以看出&#xff0c;"\n"它被识别成了一个空格显示&#…...

Python打包成exe,文件太大问题解决办法(比保姆级还保姆级)

首先我要说一下&#xff0c;如果你不在乎大小&#xff0c;此篇直接别看了&#xff0c;因为我写过直接打包的&#xff0c;就多20M而已&#xff0c;这篇就别看了&#xff0c;点击查看不在乎大小直接打包这篇我觉得简单的令人发指 不废话&#xff0c;照葫芦画瓢就好 第1步&#…...

CSS弹性布局flex属性整理

1.align-items align-items属性&#xff1a;指定弹性布局内垂直方向的对齐方向。 常用属性&#xff1a; center 垂直居中展示 flex-start 头部对齐 flex-end 底部对齐 2. justify-content justify-content属性&#xff1a;属性&#xff08;水平&#xff09;对齐弹…...

14个你需要知道的实用CSS技巧

让我们学习一些实用的 CSS 技巧&#xff0c;以提升我们的工作效率。这些 CSS 技巧将帮助我们开发人员快速高效地构建项目。 现在&#xff0c;让我们开始吧。 1.CSS :in-range 和 :out-of-range 伪类 这些伪类用于在指定范围限制之内和之外设置输入样式。 (a) : 在范围内 如…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter

java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用&#xff08;Math::max&#xff09; 2 函数接口…...