C语言拾遗——strtok

今天刷PAT的时候用到了这个strtok函数,顺手就记录一下

strtok函数包含于头文件string.h

语法:char *strtok( char *str1, const char *str2 );

功能:函数返回字符串str1中紧接“标记”的部分的指针, 字符串str2是作为标记的分隔符。如果分隔标记没有找到,函数返回NULL。为了将字符串转换成标记,第一次调用str1 指向作为标记的分隔符。之后所以的调用str1 都应为NULL

下面是测试代码

#include <stdio.h>
#include <string.h> int main(void)
{
char p[] = "My name is zzy.";
char tmp[20];
char *sep = " ";
char *token = NULL; strcpy(tmp, p); for (token = strtok(tmp, sep); token != NULL; token = strtok(NULL, sep))
{
printf("%s\n", token);
} return 0;
}

运行结果:

讨论一下为什么第二个strtok的第一个参数一定为NULL

strtok的原型如下:

_CRTIMP char* __cdecl __MINGW_NOTHROW	strtok (char*, const char*);

这个函数涉及两个指针,除了形参之外

第一个指针 pointer_a 用来指向函数返回的字符串,这个字符串是被原字符串OriginalString被seps中的字符截断后的第一个字符串。

第二个指针 pointer_b 用来指向OriginalString中,匹配截断字串seps的位置

如果在第二次函数调用的时候,第一个参数不是设置为NULL而是设为原来的字符串”My name is zzy.”,那么讲永远返回”My”并且也将陷入死循环。
为何会出现这种结果呢?

其实认真想想就很清楚啦。

第一次传入字符串”My name is zzy.” 中匹配token(即参数seps代表的各种字符)中所指定的字符的位置在My和name之间, 函数的返回值pointer_a为一个指向”My”的指。

指针此时,pointer_b指向My和name之间的位置,代表pointer_b之前的位置已经进行过查找匹配了。

这样,在循环体之内进行第二次函数调用的时候,只要把strtok()的第一个参数设置为NULL,就可以直接从pointer_b位置开始进行查找匹配了。 pointer_b 会保持之前的位置一直指下去

所以,NULL的作用只是为了使得每次调用时,都不是从”My name is zzy.”的头开始,而是从上次调用时查找所停止的位置开始的啦。如此循环下去,直到无法再找到匹配token的位置的时候,这样就实现了把”My name is zzy”按照token进行分隔的效果啦O(∩_∩)O

C语言拾遗——strtok的更多相关文章

  1. C语言拾遗(一)

    越来越体会到C语言的重要性,不管是在计算机底层的理解上,还是在算法数据结构上,所以遂决定重新拾起C语言,不定期更新一些知识点. 推荐博客:http://blog.csdn.net/itcastcpp ...

  2. C语言拾遗

    1. 没C++那么恶心的const C语言中的const修饰符用于修饰一个变量是const属性的.被C语言的const修饰的变量具有只读属性,并且不能被修改. const修饰的变量 != 常量,con ...

  3. C语言拾遗--static

    C程序一直由下列部分组成: 正文段——CPU执行的机器指令部分:一个程序只有一个副本:只读,防止程序由于意外事故而修改自身指令: 初始化数据段(数据段)——在程序中所有赋了初值的全局变量,存放在这里. ...

  4. C语言拾遗——inttypes.h

    今天偶然间看到这个头文件inttypes,好奇有什么用,去找度娘玩了一波,发现这头文件挺有意思的. 这个头文件适配于C99标准,它提供整数输入的各种进制转换的宏,这是在Ubuntu上扣下来的代码(wi ...

  5. C语言拾遗——sscanf

    今天写题用到了sscanf,怕忘赶紧记录一下 去百度了一下这玩意的函数原型好像是长这样的,微软上扣下来的  int sscanf( const char *buffer, const char *fo ...

  6. c语言,数据类型转换

    在执行算术运算时,计算机比C语言的限制更多.为了让计算机执行算术运算,通常要求操作数有相同的大小(即位的数量相同),并且要求存储的方式也相同.计算机可能可以直接将两个16位整数相加,但是不能直接将16 ...

  7. Go语言核心36讲(导读)--学习笔记

    目录 开篇词 | 跟着学,你也能成为Go语言高手 导读 | 写给0基础入门的Go语言学习者 导读 | 学习专栏的正确姿势 开篇词 | 跟着学,你也能成为Go语言高手 Go 语言是由 Google 出品 ...

  8. iOS-C基础

    iOS开发系列--C语言之基础知识 概览 当前移动开发的趋势已经势不可挡,这个系列希望浅谈一下个人对IOS开发的一些见解,这个IOS系列计划从几个角度去说IOS开发: C语言 OC基础 IOS开发(i ...

  9. 自学导航页(待续ing)

    1 博客导航1.1 linuxlinux全线教程–提供了linux教程,服务器管理教程,BSD教程,还有编程语言(C/Java/Python/Perl),以及网络等全栈学习教程 1.2 存储技术NoS ...

随机推荐

  1. bash脚本编程

    一.bash中的变量 变量类型: 本地变量:只对当前shell进程有效,对其子shell以及其它shell都无效;   定义变量:[set]Var_name="value" 变量赋 ...

  2. .net工作流设计器

    源码地址 Github: https://github.com/chengderen/Smartflow-Sharp 简要说明 https://www.smartflow-sharp.com/doc. ...

  3. Android音频录制MediaRecorder之简易的录音软件实现代码(转)

    原文:http://www.jb51.net/article/46182.htm Android音频录制MediaRecorder之简易的录音软件实现代码 这篇文章主要介绍了Android音频录制Me ...

  4. redis集群配置文件

    bind xxx.xxx.xxx.xxx 绑定redis服务器网卡IP,默认为127.,即本地回环地址.这样的话,访问redis服务只能通过本机的客户端连接,而无法通过远程连接.如果bind选项为空的 ...

  5. 笔记||Python3进阶之装饰器

    # 装饰器# 特征: 是用一个@开头的字符串# 装饰器通常用来装饰函数.或者类的方法# 被装饰后的函数,通常是在原有的函数基础上,会多出增加一点功能# 一般来说装饰器本身也是一个函数## def te ...

  6. PaperReading20200223

    CanChen ggchen@mail.ustc.edu.cn   AdaBatch Motivation: Current stochastic gradient descend methods u ...

  7. Intent的常用属性action和category

    设置隐式跳转 首先在我们按钮监听器中添加 Intent i=new Intent(); //参数为字符串,可以添加包名.活动名 i.setAction("com.example.aaaaa. ...

  8. LoRaWAN协议(一)------架构解析

    摘自:http://www.cnblogs.com/answerinthewind/p/6200497.html LoRaWAN协议(一)-----架构解析 (1)LoRaWAN分层 LoRaWAN总 ...

  9. WC2020「Fantasie」

    由于某些不可抗拒因素,这篇文章鸽了

  10. redis api-zset