解析spritf和sscanf与模拟常用字符串函数strchr,strtok(二)
今天又来继续我们的字符串函数的文章,这也是最后一篇了。希望这两篇文章能让各位理解透字符串函数。
目录
strchr
strtok
sprintf和sscanf
strchr
strchr 是一个用于在字符串中查找特定字符首次出现位置的函数。以下是解析和模拟实现 strchr 函数的示例:
解析 strchr 函数:
#include <stdio.h>// 解析 strchr 函数
void parse_strchr() {const char *string = "Hello, World!";char target = 'l';// 使用 strchr 函数查找字符const char *found = strchr(string, target);if (found != NULL) {printf("Character '%c' found at index: %zu\n", target, found - string);} else {printf("Character '%c' not found in string\n", target);}
}int main() {parse_strchr();return 0;
}
在上述示例中,我们定义了一个字符串 string 和要查找的目标字符 target 。然后,使用 strchr 函数在字符串中查找目标字符,并将找到的位置存储在 found 变量中。根据 found 是否为 NULL ,我们输出相应的结果。
模拟实现 strchr 函数:
#include <stdio.h>// 模拟实现 strchr 函数
const char * my_strchr(const char * string, char target)
{for (; *string != '\0'; string++){if (*string == target){return string;}}return NULL;
}int main() {const char * string = "Hello, World!";char target = 'l';// 使用模拟的 my_strchr 函数查找字符const char * found = my_strchr(string, target);if (found != NULL){printf("Character'%c'found at index:%zu\n", target, found - string);}else {printf("Character'%c' not found in string\n", target);}return 0;
}
在模拟实现中,我们使用一个循环遍历字符串中的每个字符。如果找到了与目标字符匹配的字符,就返回该字符的地址。如果循环结束后仍未找到,返回 NULL 。
这两种方法(解析和模拟实现)都可以用来在字符串中查找特定字符。使用标准库中的 strchr 函数通常更方便和可靠,但模拟实现可以帮助你更好地理解其工作原理。
strtok
strtok 是一个用于分割字符串的函数。它根据指定的分隔符将字符串分割成多个部分,并可以逐个提取这些部分。
下面是模拟和解析 strtok 函数的示例:
解析 strtok 函数:
#include <stdio.h>
#include <string.h>// 解析 strtok 函数
void parse_strtok() {char string[] = "apple,banana,cherry";char delimiter[] = ",";// 使用 strtok 函数分割字符串char * token = strtok(string, delimiter);while (token != NULL) {printf("%s\n", token);token = strtok(NULL, delimiter);}
}int main() {parse_strtok();return 0;
}
在这个示例中,我们直接使用了标准库中的 strtok 函数来分割字符串,并打印每个部分。
模拟 strtok 函数:
#include <stdio.h>
#include <string.h>// 模拟 strtok 函数
char * my_strtok(char * str, const char * delimiter)
{static char* token = NULL;if (str == NULL) {return NULL;}while (1){// 查找下一个分隔符的位置char* next = strstr(str, delimiter);// 如果找到分隔符if (next != NULL) {*next = '\n';}else if (next == NULL)break;}token = str;return token;
}int main() {char string[] = "apple,banana,cherry";char delimiter[] = ",";// 使用模拟的 my_strtok 函数分割字符串char * token = my_strtok(string, delimiter);while (token != NULL) {printf("%s\n", token);token = my_strtok(NULL, delimiter);}return 0;
}
在上述示例中,我们模拟了 strtok 函数的行为。通过使用 strstr 函数查找分隔符的位置,并将其设置为字符串的换行符。然后,返回找到的下一个部分的指针。
无论是模拟还是直接使用 strtok ,它们的基本原理都是根据指定的分隔符将字符串分割成多个部分。需要注意的是, strtok 函数会修改原始字符串,并且在多次调用时需要注意处理 NULL 指针的情况。
sprintf和sscanf
sprintf 是一个变参函数,用于格式化字符串并将结果写入到指定的缓冲区中,其函数声明为 int sprintf(char *buffer, const char *format, ...) 。下面是对各参数的详细解释:
- buffer :是 char 类型的指针,指向要写入的字符串的指针。
- format :格式化字符串,即在程序中指定的格式。
- argument :可选参数,可以为任意类型的数据,可以有一个或多个参数。
该函数的返回值是写入到缓冲区中的字符数,不包括字符串结尾的空字符 \0 。下面是一些常见的用法示例:
- 格式化数字字符串:
// 把整数123打印成一个字符串保存在s中
sprintf(s, "%d", 123);
// 产生 "123"
- 控制浮点数打印格式:
// 保留小数点后6位数字
sprintf(s, "%f", 3.1415926);
// 产生 "3.141593"
- 连接字符串:
// 连接字符串
char *who = "I";
char *whom = "52PHP";
sprintf(s, "%s love %s.", who, whom);
// 产生 "I love 52PHP. "
- 打印整数和浮点数时可以指定宽度:
// 指定宽度
char a1[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
char a2[] = {'H', 'I', 'J', 'K', 'L', 'M', 'N'};
sprintf(s, "%.7s%.7s", a1, a2);
// 产生 "ABCDEFGHIJKLMN"
需要注意的是, sprintf 函数在字符串中插入变量时不会进行边界检查,如果格式化字符串和变参列表不匹配,可能会导致缓冲区溢出或其他问题。因此,在使用 sprintf 函数时,应确保格式化字符串和变参列表的匹配,并确保缓冲区的大小足够容纳输出结果。
sscanf 函数是一个用于从字符串中读取数据的 C 语言函数,与 scanf 函数类似,但是它的输入源是一个字符串而不是标准输入。 sscanf 函数的声明如下:
int sscanf(const char *str, const char *format, ...)
参数说明:
- str :这是 C 字符串,是函数检索数据的源。
- format :这是 C 字符串,包含了以下各项中的一个或多个:空格字符、非空格字符 和 format 说明符 。
- ... :这是可变参数,为对应的附加参数所指向的数据指定一个不同于整型(针对 d、i 和 n)、无符号整型(针对 o、u 和 x)或浮点型(针对 e、f 和 g)的大小。
该函数会将参数 str 的字符串根据参数 format 字符串来转换并格式化数据,转换后的结果存于对应的参数内。返回值为成功匹配和赋值的个数,如果没有成功匹配的项,则返回 0 。
下面是一些常见的用法示例:
- 从字符串中读取一个字符:
char c;
sscanf("Hello", "%c", &c);
- 从字符串中读取一个整数:
int i;
sscanf("12345", "%d", &i);
- 从字符串中读取一个浮点数:
float f;
sscanf("3.1415", "%f", &f);
- 从字符串中读取多个数据:
int i, j;
char s[50];
sscanf("12 56", "%d %s", &i, s, &j);
需要注意的是, sscanf 函数在字符串中读取数据时不会进行边界检查,可能会导致缓冲区溢出或其他问题。因此,在使用 sprintf 函数时,应确保字符串中的数据格式与 format 字符串中的格式说明符相匹配,并确保缓冲区的大小足够容纳读取的数据。
sprintf和sscanf的模拟实现太复杂就不模拟了。
文章已到末尾,希望多多支持。
相关文章:

解析spritf和sscanf与模拟常用字符串函数strchr,strtok(二)
今天又来继续我们的字符串函数的文章,这也是最后一篇了。希望这两篇文章能让各位理解透字符串函数。 目录 strchr strtok sprintf和sscanf strchr strchr 是一个用于在字符串中查找特定字符首次出现位置的函数。以下是解析和模拟实现 strchr 函数的示例&…...

备战蓝桥杯---搜索(进阶4)
话不多说,直接看题: 下面是分析: (ab)%c(a%cb%c)%c; (a*b)%c(a%c*b%c)%c; 因此,如果两个长度不一样的值%m为相同值,那就舍弃长的(因为再加1位只不过是原来值*10那位值,因此他们得出的%m还是同…...

51单片机基础(C语言):定时器时钟
1.使用定时器 1 和LCD1602设计一个简易数字时钟。 main.c #include <REGX52.H> #include "Delay.h" #include "LCD1602.h" #include "Timer0.h"unsigned char Sec55,Min59,Hour23;void main() {LCD_Init();Timer0Init();LCD_ShowString(…...

单片机无线发射的原理剖析
目录 一、EV1527编码格式 二、OOK&ASK的简单了解 三、433MHZ 四、单片机的地址ID 五、基于STC15W104单片机实现无线通信 无线发射主要运用到了三个知识点:EV1527格式;OOk;433MHZ。下面我们来分别阐述: EV1527是数据的编…...

Redis的过期键的删除策略
我们都知道,Redis是key-value数据库,我们可以设置Redis中缓存的key的过期时间。Redis的过期策略就是指当Redis中缓存的key过期了,Redis如何处理。 过期策略通常有以下三种: 定时过期:每个设置过期时间的key都需要创建…...

放假--寒假自学版 day1(补2.5)
fread 函数: 今日练习 C语言面试题5道~ 1. static 有什么用途?(请至少说明两种) 1) 限制变量的作用域 2) 设置变量的存储域 2. 引用与指针有什么区别? 1) 引用必须被初始化,指针不必。 2) 引用初始…...

LLM(5) | Encoder 和 Decoder 架构
LLM(5) | Encoder 和 Decoder 架构 文章目录 LLM(5) | Encoder 和 Decoder 架构0. 目的1. 概要2. encoder 和 decoder 风格的 transformer (Encoder- And Decoder-Style Transformers)原始的 transformer (The original transformer)编码器 (Encoders)解码器 (Decoders)编码器和…...

CV | Medical-SAM-Adapter论文详解及项目实现
******************************* 👩⚕️ 医学影像相关直达👨⚕️******************************* CV | SAM在医学影像上的模型调研【20240207更新版】-CSDN博客 CV | Segment Anything论文详解及代码实现 本文主要讲解Medical-SAM-Adapter论文及项…...

C++初阶:容器(Containers)vector常用接口详解
介绍完了string类的相关内容后:C初阶:适合新手的手撕string类(模拟实现string类) 接下来进入新的篇章,容器vector介绍: 文章目录 1.vector的初步介绍2.vector的定义(constructor)3.v…...

flink写入es的参数解析
ElasticsearchSink内部使用BulkProcessor一次将一批动作(ActionRequest)发送到ES集群。在发送批量动作前,BulkProcessor先缓存,再刷新。缓存刷新的间隔,支持基于Action数量、基于Action大小、基于时间间隔3种策略。BulkProcessor支持在同一次…...

逆向工程:揭开科技神秘面纱的艺术
在当今这个科技飞速发展的时代,我们每天都在与各种电子产品、软件应用打交道。然而,你是否想过,这些看似复杂的高科技产品是如何被创造出来的?今天,我们就来探讨一下逆向工程这一神秘而又令人着迷的领域。 一、什么是…...

决策树的相关知识点
📕参考:ysu老师课件西瓜书 1.决策树的基本概念 【决策树】:决策树是一种描述对样本数据进行分类的树形结构模型,由节点和有向边组成。其中每个内部节点表示一个属性上的判断,每个分支代表一个判断结果的输出ÿ…...

【数据结构】单向链表实现 超详细
目录 一. 单链表的实现 1.准备工作及其注意事项 1.1 先创建三个文件 1.2 注意事项:帮助高效记忆和理解 2.链表的基本功能接口 2.0 创建一个 链表 2.1 链表的打印 3.链表的创建新节点接口 4.链表的节点插入功能接口 4.1 尾插接口 4.2 头插接口 4.3 指定位…...

Opencc4j 开源中文繁简体使用介绍
Opencc4j Opencc4j 支持中文繁简体转换,考虑到词组级别。 Features 特点 严格区分「一简对多繁」和「一简对多异」。 完全兼容异体字,可以实现动态替换。 严格审校一简对多繁词条,原则为「能分则不合」。 词库和函数库完全分离,…...

vue 下载二进制文件
文章目录 概要技术细节 概要 vue 下载后端返回的二进制文件流 技术细节 import axios from "axios"; const baseUrl process.env.VUE_APP_BASE_API; //downLoadPdf("/pdf/download?pdfName" res .pdf, res); export function downLoadPdf(str, fil…...

数据结构之堆排序
对于几个元素的关键字序列{K1,K2,…,Kn},当且仅当满足下列关系时称其为堆,其中 2i 和2i1应不大于n。 { K i ≤ K 2 i 1 K i ≤ K 2 i 或 { K i ≥ K 2 i 1 K i ≥ K 2 i {\huge \{}^{K_i≤K_{2i}} _{K_i≤K_{2i1}} …...

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之ScrollBar组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之ScrollBar组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、ScrollBar组件 鸿蒙(HarmonyOS)滚动条组件ScrollBar&…...

读论文:DiffBIR: Towards Blind Image Restoration with Generative Diffusion Prior
DiffBIR 发表于2023年的ICCV,是一种基于生成扩散先验的盲图像恢复模型。它通过两个阶段的处理来去除图像的退化,并细化图像的细节。DiffBIR 的优势在于提供高质量的图像恢复结果,并且具有灵活的参数设置,可以在保真度和质量之间进…...

基于微信小程序的新生报到系统的研究与实现,附源码
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...

分享一下 uniapp 打包安卓apk
首先需要安装 Java 环境,这里就不做解释了 第二步:打开 mac 终端 / cmd 命令行工具 使用keytool -genkey命令生成证书 keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore *testalias 是证书别名&am…...

DevOps落地笔记-21|业务价值:软件发布的最终目的
上一课时介绍如何度量软件的内部质量和外部质量。在外部质量中,我们提到用户满意度是衡量软件外部质量的关键因素。“敏捷宣言”的第一条原则规定:“我们最重要的目标,是通过持续不断的及早交付有价值的软件使用户满意”。从这一点也可以看出…...

【动态规划】【前缀和】【数学】2338. 统计理想数组的数目
作者推荐 【动态规划】【前缀和】【C算法】LCP 57. 打地鼠 本文涉及知识点 动态规划汇总 C算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 LeetCode:2338. 统计理想数组的数目 给你两个整数 n 和 maxValue ,用于描述一个 理想…...

【已解决】onnx转换为rknn置信度大于1,图像出现乱框问题解决
前言 环境介绍: 1.编译环境 Ubuntu 18.04.5 LTS 2.RKNN版本 py3.8-rknn2-1.4.0 3.单板 迅为itop-3568开发板 一、现象 采用yolov5训练并将pt转换为onnx,再将onnx采用py3.8-rknn2-1.4.0推理转换为rknn出现置信度大于1,并且图像乱框问题…...

多路服务器技术如何处理大量并发请求?
在当今的互联网时代,随着用户数量的爆炸性增长和业务规模的扩大,多路服务器技术已成为处理大量并发请求的关键手段。多路服务器技术是一种并行处理技术,它可以通过多个服务器同时处理来自不同用户的请求,从而显著提高系统的整体性…...

SpringBoot - 不加 @EnableCaching 标签也一样可以在 Redis 中存储缓存?
网上文章都是说需要在 Application 上加 EnableCaching 注解才能让缓存使用 Redis,但是测试发现不用 EnableCaching 也可以使用 Redis,是网上文章有问题吗? 现在 Application 上用了 EnableAsync,SpringBootApplication࿰…...

Linux------命令行参数
目录 前言 一、main函数的参数 二、命令行控制实现计算器 三、实现touch指令 前言 当我们在命令行输入 ls -al ,可以查看当前文件夹下所有文件的信息,还有其他的如rm,touch等指令,都可以帮我们完成相应的操作。 其实运行这些…...

LLM少样本示例的上下文学习在Text-to-SQL任务中的探索
导语 本文探索了如何通过各种提示设计策略,来增强大型语言模型(LLMs)在Few-shot In-context Learning中的文本到SQL转换能力。通过使用示例SQL查询的句法结构来检索演示示例,并选择同时追求多样性和相似性的示例可以提高性能&…...

双非本科准备秋招(19.2)—— 设计模式之保护式暂停
一、wait & notify wait能让线程进入waiting状态,这时候就需要比较一下和sleep的区别了。 sleep vs wait 1) sleep 是 Thread 方法,而 wait 是 Object 的方法 2) sleep 不需要强制和 synchronized 配合使用,但 wait 强制和 s…...

使用SpringMVC实现功能
目录 一、计算器 1、前端页面 2、服务器处理请求 3、效果 二、用户登陆系统 1、前端页面 (1)登陆页面 (2)欢迎页面 2、前端页面发送请求--服务器处理请求 3、效果 三、留言板 1、前端页面 2、前端页面发送请求 &…...

spring aop实现接口超时处理组件
文章目录 实现思路实现代码starter组件 实现思路 这里使用FutureTask,它通过get方法以阻塞的方式获取执行结果,并设定超时时间: public V get() throws InterruptedException, ExecutionException ;public V get(long timeout, TimeUnit un…...