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)的功能,使其能更好地应用于生成唐诗相关内容的…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
