0

0

strtok函数的用法是什么

coldplay.xixi

coldplay.xixi

发布时间:2020-10-28 09:48:27

|

17824人浏览过

|

来源于php中文网

原创

strtok函数的用法:1、作用于字符串s,以delim中的字符为分界符,将s切分成一个个子串;2、如果s为空值NULL,则函数保存的指针【SAVE_PTR】在下一次调用中将作为起始位置。

strtok函数的用法是什么

相关免费推荐:编程视频课程

strtok函数的用法:

一、函数的简介

         函数原型:char *strtok(char *s, char *delim)

         功能:作用于字符串s,以delim中的字符为分界符,将s切分成一个个子串;如果,s为空值NULL,则函数保存的指针SAVE_PTR在下一次调用中将作为起始位置。

         返回值:分隔符匹配到的第一个子串

二、主要内容

        1、函数的作用是分解字符串,所谓分解,即没有生成新串,只是在s所指向的内容首次出现分界符的位置,将分界符修改成了'/0’,故第一次用strtok()返回第一个子串

         2、第一次提取子串完毕之后,继续对源字符串s进行提取,应在其后(第二次,第三次。。。第n次)的调用中将strtok的第一个参数赋为空值NULL(表示函数继续从上   一次调用隐式保存的位置,继续分解字符串;对于前一次次调用来说,第一次调用结束前用一个this指针指向了分界符的下一位

         3、当this指针指向“\0” 时,即没有被分割的子串了,此时则返回NULL

         4、可以把delim理解为分隔符的集合delim中的字符均可以作为分隔符。

         5、strtok在调用的时候,如果起始位置即为分隔符,则忽略了起始位置开始的分隔符


三、使用strtok需要注意的有以下几点:

1.函数的作用是分解字符串,所谓分解,即没有生成新串,只是在s所指向的内容上做了些手脚而已。因此,源字符串s发生了变化!

设源字符串s为 char buffer[INFO_MAX_SZ]=",Fred male 25,John male 62,Anna female 16";  过滤字符串delim为 char *delim = " ",即空格为分界符。

 5fc2ead8ed6e5319671c5f17bca2492.png

上图的代码会产生这样的结果:

d6d435e4c9acec5c9ee8fb3dbf8daf6.png

首先,buffer发生了变化。如果此时打印buffer的值,会显示“,Fred”,而后面" male 25…16”不翼而飞了。实际上,strtok函数根据delim中的分界符,找到其首次出现的位置,即Fred后面那个空格(buffer[5]),将其修改成了'/0’。其余位置不变。这就很好解释为什么打印buffer的值只能出现“,Fred”,而非buffer中的全部内容了。因此,使用strtok时一定要慎重,以防止源字符串被修改。 

理解了buffer的变化,就很好解释函数的返回值了。返回值buf为分界符之前的子串(其实这个说法并不确切,详见"3”中对于返回值的详细说明)。注意,由变量的地址可知,buf依然指向源字符串。

64513f809d395693aa82d8b5c7f3cb4.png

分界符delim没有发生变化,就不再截图了。

 

2.若要在第一次提取子串完毕之后,继续对源字符串s进行提取,应在其后(第二次,第三次。。。第n次)的调用中将strtok的第一个参数赋为空值NULL。

8b6cdef3d01432f9e3ecd5f47f65ecd.png

第一次调用的结果如前文所述,提取出了",Fred”。我们还想继续以空格为分界,提取出后面的"male”等。由上图可以看到,第一次之后的调用我们都给strtok的第一个参数传递了空值NULL(表示函数继续从上一次调用隐式保存的位置,继续分解字符串;对于上述的第二次调用来说,第一次调用结束前用一个this指针指向了分界符的下一位,即'm’所在的位置),这样可依次提取出

fbe7f1ecde9c54eb69115199d8b2e8b.pnga22f976065ff3e7643db39249e71283.png 。。。。以此类推。。。。。

至于为什么要赋空值,要么你就记住结论,要么去查strtok的源代码。本文的最后会有一些介绍。

当然也有部分爱钻牛角尖的人,非不按套路出牌,要看看不赋空值继续赋值为buffer会有什么结果。其实,答案想也能想的到。再一次传递buffer,相当于还从字符串的开头查找分界符delim,而且此时buffer已经被修改(可见的部分只剩下",Fred”),因此,其结果必然是找不到分界符delim。

 

3.关于函数返回值的探讨

由"1”中所述,在提取到子串的情况下,strtok的返回值(假设返回值赋给了指针buf)是提取出的子串的指针。这个指针指向的是子串在源字符串中的起始位置。子串末尾的下一个字符在提取前为分隔符,提取后被修改成了'/0’。因此,若打印buf的值,可以成功的输出子串的内容。

手机在线人工冲值
手机在线人工冲值

说明:我不知道这个系统还能用到什么地方!他的运作方式是这样的,客户在其他地方比如掏宝购买了 你得卡,然后在你的网站进行冲值,你得有人登陆并看着后台,如果有人冲值,就会刷出记录,手工冲值完毕后,你得点击 [冲值完毕],客户的页面 就会返回 冲值信息!安装:上传所有文件,倒入(sql.txt)mysql数据库,使用myphpadminphplib 777phplib/sys.php 777phplib

下载

在没有提取到子串的情况下,函数会返回什么值呢?

4ff4ee3314fdf15017688e23450b751.png

由上图可以看到buffer中并不包含分界符delim。调用strtok后buf的值为

8c0afe05443b8da09df557257c94d94.png

因为没有找到,源字符串buffer没有发生改变,buf指向源字符串的首地址,打印输出的值为整个字符串的完整值。

什么时候函数的返回值为空值NULL呢?

百度百科上说,“当没有被分割的串时则返回NULL。”这是一个很模棱两可的说法。如果想要确切的了解清楚这个问题,可能需要看一下strtok的实现原理。这里先以实验说明。

e37f40f54d85f992f4bd25bef712570.png

第一次调用strtok,毫无疑问,buf指向",Fred”。

第二次调用strtok,由于第一个参数为NULL,表示函数继续以上次调用所保存的this指针的位置开始分解,即对"male 25”分解。分解完毕后,buf指向"male”。

第三次调用strtok,参数继续设定为NULL,此时即对第二次保存的this指针的位置开始分解,即对"25”分解。因为无法找到包含分隔符delim的子串,所以buf指向"25”。

2c325eb6fa86c1cd6c804b35b2669bb.png

第四次调用,参数仍为NULL,此时第三次调用保存的this指针已指向字符串的末尾'/0’,已无法再进行分解。因此函数返回NULL,这也就是百度百科中所提到的“当没有被分割的串时函数返回NULL。”

db5252ad4fc5a8c1ea94bd541a94da2.png

 

4.参数 分隔符delim的探讨(delim是分隔符的集合)

很多人在使用strtok的时候,都想当然的以为函数在分割字符串时完整匹配分隔符delim,比如delim=”ab”,则对于"acdab”这个字符串,函数提取出的是"acd”。至少我在第一次使用的时候也是这么认为的。其实我们都错了,我是在看函数的源代码时才发现这个问题的,且看下面的例子。

068cdb90ad4024883f3519457b3cab5.png

源字符串为buffer,分隔符delim为 逗号和空格,按照一般的想法我们会以为调用函数后,buf的值为"Fred,male,25”,结果是这样么?

033b30edc6b8ada9f9cad3304ea38ea.png

第一次调用之后的结果竟然是"Fred”,而非我们所想的结果。这是为什么呢?

我们回到GNU C Library中对strtok的功能定义:“Parse S into tokens separated by characters in DELIM”。也就是说包含在delim中的字符均可以作为分隔符,而非严格匹配。可以把delim理解为分隔符的集合。这一点是非常重要的~

当然,我们在分解字符串的时候,很少使用多个分隔符。这也导致,很多人在写例子的时候只讨论了一个分隔符的情况。有更多的人在看例子的时候也就错误的认识了delim的作用。

5.待分解的字符串,首字符就为分隔符

首字符为分隔符不能算作一个很特殊的情况。按照常规的分解思路也能正确分解字符串。

我想说明的是,strtok对于这种情况采用了比常规处理更快的方式。

241af81bb6e3701f83ae80b7f1b7639.png

如上图例子所示。仅用一次调用就可以得到以逗号分隔的字符串"Fred male 25”,而F前面的','被忽略了。由此可见,strtok在调用的时候忽略了起始位置开始的分隔符。这一点,可以从strtok的源代码得到证实。

6.不能向第一个参数传递字符串常量!

本文中所举的例子都将源字符串保存为字符串数组变量。若你将源字符串定义成字符串常量,可想而知,程序会因为strtok函数试图修改源字符串的值,而抛出异常。

da4ea861caf33ceaaf36b89e2012c8f.png

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

231

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

435

2024.03.01

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1463

2023.10.24

字符串常量的表示方法
字符串常量的表示方法

字符串常量的表示方法:1、使用引号;2、转义字符;3、多行字符串;4、原始字符串;5、字符串连接;6、字符串字面量和对象;7、编码问题。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

139

2023.12.26

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

254

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

206

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1463

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

617

2023.11.24

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

36

2026.01.14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 11.8万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.1万人学习

NumPy 教程
NumPy 教程

共44课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号