C语言strtok()函数用法详解!
strtok
是 C 标准库中的字符串分割函数,用于将一个字符串拆分成多个部分(token),以某些字符(称为分隔符)为界限。
函数原型
char *strtok(char *str, const char *delim);
-
参数:
str
:待分割的字符串。如果是第一次调用,传入要分割的字符串;之后的调用需传入NULL
,以继续上一次的分割。delim
:字符串,包含所有分隔符的字符集合。例如," "
(空格)或"/"(斜杠)
。
-
返回值:
- 返回指向字符串中 当前部分 的指针。
- 如果没有更多部分可返回,返回
NULL
。
用法规则
- 初次调用时,传入字符串
str
,函数会从str
中找到第一个部分。 - 函数会用
'\0'
替换找到的分隔符(破坏原字符串)。 - 后续调用时,传入
NULL
,函数会继续从上次结束的位置查找下一部分。 - 不能在多线程环境中使用,因为
strtok
使用的是静态变量保存状态。
示例
#include <stdio.h>
#include <string.h>int main() {char str[] = "C programming is fun";const char *delim = " "; // 用空格作为分隔符char *token;// 初次调用 strtoktoken = strtok(str, delim);while (token != NULL) {printf("%s\n", token); // 打印分割的每一部分token = strtok(NULL, delim); // 后续调用}return 0;
}
输出:
C
programming
is
fun
注意事项
-
原字符串被修改:
strtok
会在分隔符处插入'\0'
,因此原字符串内容会被破坏。如果需要保留原字符串,请先复制到一个新字符串再操作。 -
不能并发使用:由于
strtok
使用内部静态变量保存状态,它在多线程程序中不安全。多线程环境下,请使用strtok_r
。
分隔符的处理
分隔符 delim
可以包含多个字符,strtok
会将所有出现在 delim
中的字符视为分隔符。例如:
#include <stdio.h>
#include <string.h>int main() {char str[] = "apple;orange,banana|grape";const char *delim = ";,|"; // 多个分隔符char *token;token = strtok(str, delim);while (token != NULL) {printf("%s\n", token);token = strtok(NULL, delim);}return 0;
}
输出:
apple
orange
banana
grape
如何在多线程中使用?
在多线程环境下,使用 strtok_r
(线程安全版本)。函数原型如下:
char *strtok_r(char *str, const char *delim, char **saveptr);
参数说明
str
:首次调用传入要分割的字符串,后续调用传入NULL
。delim
:分隔符集合。saveptr
:保存分割状态的指针变量,需由调用者提供。
示例
#include <stdio.h>
#include <string.h>int main() {char str[] = "apple;orange,banana|grape";const char *delim = ";,|";char *token;char *saveptr; // 保存状态token = strtok_r(str, delim, &saveptr);while (token != NULL) {printf("%s\n", token);token = strtok_r(NULL, delim, &saveptr);}return 0;
}
输出:
apple
orange
banana
grape
为什么需要传入 NULL
?
strtok
函数内部使用了一个 静态指针 来记录分割状态。这个静态指针会指向原字符串中上一次分割结束的位置。在首次调用时,strtok
初始化这个指针为传入的字符串地址。在后续调用时,通过传入 NULL
,strtok
会继续从这个内部静态指针的位置接着分割。
静态指针的工作原理
-
初次调用:
token = strtok(str, delim);
- 参数
str
是待分割字符串。 strtok
将分隔符替换为'\0'
,并返回找到的第一个分割部分,同时保存分割结束的位置到静态指针中。
- 参数
-
后续调用:
token = strtok(NULL, delim);
- 参数
NULL
告诉strtok
使用保存的静态指针,从上次分割结束的位置继续分割。 - 每次分割后,
strtok
会更新静态指针的位置。
- 参数
示例分析
#include <stdio.h>
#include <string.h>int main() {char str[] = "C,programming,is,fun";const char *delim = ",";char *token;// 初次调用 strtoktoken = strtok(str, delim);printf("First token: %s\n", token); // 输出 "C"// 后续调用 strtoktoken = strtok(NULL, delim);printf("Second token: %s\n", token); // 输出 "programming"token = strtok(NULL, delim);printf("Third token: %s\n", token); // 输出 "is"token = strtok(NULL, delim);printf("Fourth token: %s\n", token); // 输出 "fun"token = strtok(NULL, delim);printf("Final token: %s\n", token); // 输出 "(null)",分割完成return 0;
}
输出:
First token: C
Second token: programming
Third token: is
Fourth token: fun
Final token: (null)
内部指针变化:
- 初次调用:
str
是"C,programming,is,fun"
。- 静态指针保存分割后的位置
"programming,is,fun"
。
- 第二次调用:
- 使用静态指针继续分割。
- 静态指针更新为
"is,fun"
。
- 第三次调用:
- 静态指针更新为
"fun"
。
- 静态指针更新为
- 第四次调用:
- 静态指针更新为
NULL
。
- 静态指针更新为
静态指针的局限性
1. 线程不安全
strtok
的静态指针是全局共享的,多个线程同时调用 strtok
会导致状态混乱。
解决方案:使用线程安全的 strtok_r
函数,它将状态保存到用户提供的指针(而非静态变量)中。
2. 不能同时分割多个字符串
因为 strtok
的静态指针只能记录一个字符串的分割状态。如果需要同时分割多个字符串,应使用其他方法(如 strtok_r
或自定义逻辑)。
总结
strtok
用于字符串分割,但会修改原字符串,并且线程不安全。- 多线程环境下,推荐使用
strtok_r
。 - 分割的字符串存储在原字符串中,指针返回的是分割后的部分,原字符串会被破坏。
相关文章:
C语言strtok()函数用法详解!
strtok 是 C 标准库中的字符串分割函数,用于将一个字符串拆分成多个部分(token),以某些字符(称为分隔符)为界限。 函数原型 char *strtok(char *str, const char *delim);参数: str:…...
【docker 拉取镜像超时问题】
问题描述 在centosStream8上安装docker,使用命令sudo docker run hello-world 后出现以下错误: Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Ti…...

模拟手机办卡项目(移动大厅)--结合面向对象、JDBC、MYSQL、dao层模式,使用JAVA控制台实现
目录 1. 项目需求 2. 项目使用的技术 3.项目需求分析 3.1 实体类和接口 4.项目结构 5.业务实现 5.1 登录 5.1.1 实现步骤 5.1.2 原生代码问题 编辑 5.1.3 解决方法 1.说明: 2. ResultSetHandler结果集处理 5.1.4 代码 5.1.5 实现后的效果图 登录成功…...
机器学习—大语言模型:推动AI新时代的引擎
云边有个稻草人-CSDN博客 目录 引言 一、大语言模型的基本原理 1. 什么是大语言模型? 2. Transformer 架构 3. 模型训练 二、大语言模型的应用场景 1. 文本生成 2. 问答系统 3. 编码助手 4. 多语言翻译 三、大语言模型的最新进展 1. GPT-4 2. 开源模型 …...

C++:探索哈希表秘密之哈希桶实现哈希
文章目录 前言一、链地址法概念二、哈希表扩容三、哈希桶插入逻辑四、析构函数五、删除逻辑六、查找七、链地址法代码实现总结 前言 前面我们用开放定址法代码实现了哈希表: C:揭秘哈希:提升查找效率的终极技巧_1 对于开放定址法来说&#…...

具身智能高校实训解决方案——从AI大模型+机器人到通用具身智能
一、 行业背景 在具身智能的发展历程中,AI 大模型的出现成为了关键的推动力量。这些大模型具有海量的参数和强大的语言理解、知识表示能力,能够为机器人的行为决策提供更丰富的信息和更智能的指导。然而,单纯的大模型在面对复杂多变的现实…...

【消息序列】详解(8):探秘物联网中设备广播服务
目录 一、概述 1.1. 定义与特点 1.2. 工作原理 1.3. 应用场景 1.4. 技术优势 二、截断寻呼(Truncated Page)流程 2.1. 截断寻呼的流程 2.2. 示例代码 2.3. 注意事项 三、无连接外围广播过程 3.1. 设备 A 启动无连接外围设备广播 3.2. 示例代…...
【RL Base】强化学习核心算法:深度Q网络(DQN)算法
📢本篇文章是博主强化学习(RL)领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅…...
深入浅出 Python 网络爬虫:从零开始构建你的数据采集工具
在大数据时代,网络爬虫作为一种数据采集技术,已经成为开发者和数据分析师不可或缺的工具。Python 凭借其强大的生态和简单易用的语言特点,在爬虫领域大放异彩。本文将带你从零开始,逐步构建一个 Python 网络爬虫,解决实…...

美国发布《联邦风险和授权管理计划 (FedRAMP) 路线图 (2024-2025)》
文章目录 前言一、战略目标实施背景2010年12月,《改革联邦信息技术管理的25点实施计划》2011年2月,《联邦云计算战略》2011年12月,《关于“云计算环境中的信息系统安全授权”的首席信息官备忘录》2022年12月,《FedRAMP 授权法案》…...

Python语法基础(三)
🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 我们这篇文章来说一下函数的返回值和匿名函数 函数的返回值 我们先来看下面的这一段函数的定义代码 # 1、返回值的意义 def func1():print(111111111------start)num166print…...
云计算之elastaicsearch logstach kibana面试题
1.ELK是什么? ELK 其实并不是一款软件,而是一整套解决方案,是三个软件产品的首字母缩写 Elasticsearch:负责日志检索和储存 Logstash:负责日志的收集和分析、处理 Kibana:负责日志的可视化 这三款软件都是开源软件,通常是配合使用,而且又先后归于 Elastic.co 公司名下,…...
【已解决】git push需要输入用户名和密码问题
解决方法: 1)查看使用的clone方式: git remote -v 2)若为HTTPS,删除原clone方式: git remote rm origin 3)添加新的clone方式: git remote add origin gitgithub.com:zludon/git_test.git …...
python的字符串处理
需求: 编写一个程序,输入一段英文句子,统计每个单词的长度,并将单词按照长度从短到长排序。 程序逻辑框图 1、用户输入一句英文句子。 2、对输入的句子进行预处理(去空格并分割为单词列表)。 3、统计每个单…...

【线程】Java多线程代码案例(2)
【线程】Java多线程代码案例(2) 一、定时器的实现1.1Java标准库定时器1.2 定时器的实现 二、线程池的实现2.1 线程池2.2 Java标准库中的线程池2.3 线程池的实现 一、定时器的实现 1.1Java标准库定时器 import java.util.Timer; import java.util.Timer…...
虚拟机之间复制文件
在防火墙关闭的前提下,您可以通过几种不同的方法将文件从一个虚拟机复制到另一个虚拟机。这里,我们假设您想要从 IP 地址为 192.168.4.5 的虚拟机上的 /tmp 文件夹复制文件到当前虚拟机(192.168.4.6)的 /tmp 文件夹下。以下是几种…...

如何为 XFS 文件系统的 /dev/centos/root 增加 800G 空间
如何为 XFS 文件系统的 /dev/centos/root 增加 800G 空间 一、前言二、准备工作三、扩展逻辑卷1. 检查现有 LVM 配置2. 扩展物理卷3. 扩展卷组4. 扩展逻辑卷四、调整文件系统大小1. 检查文件系统状态2. 扩展文件系统五、处理可能出现的问题1. 文件系统无法扩展2. 磁盘空间不足3…...

Java算法OJ(11)双指针练习
目录 1.前言 2.正文 2.1存在重复数字 2.1.1题目 2.1.2解法一代码 解析: 2.1.3解法二代码 解析: 2.2存在重复数字plus 2.2.1题目 2.2.2代码 2.2.3解析 3.小结 1.前言 哈喽大家好吖,今天来给大家分享双指针算法的相关练习&…...
44.扫雷第二部分、放置随机的雷,扫雷,炸死或成功 C语言
按照教程打完了。好几个bug都是自己打出来的。比如统计周围8个格子时,有一个各自加号填成了减号。我还以为平移了,一会显示是0一会显示是2。结果单纯的打错了。debug的时候断点放在scanf后面会顺畅一些。中间多放一些变量名方便监视。以及mine要多显示&a…...

大语言模型LLM的微调代码详解
代码的摘要说明 一、整体功能概述 这段 Python 代码主要实现了基于 Hugging Face Transformers 库对预训练语言模型(具体为 TAIDE-LX-7B-Chat 模型)进行微调(Fine-tuning)的功能,使其能更好地应用于生成唐诗相关内容的…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...