探索C语言之字符串分割函数:strtok和strsep的区别
探索C语言之字符串分割函数:strtok和strsep的区别
- 概述
- strsep - extract token from string(linux 下)
- strtok, strtok_r - extract tokens from strings
- 相同点
- 不同点
- 什么时候使用它们?
概述
在c语言中,字符串分割函数主要有两种:一是strtok函数,另一个就是strsep函数。
下面我们对这两个函数作一个详细解释说明。
strsep - extract token from string(linux 下)
#include <string.h>char *strsep(char **s, const char *delim); //会修改数据源。可重入的,注意这里虽然改动stringp的内容,主要是不在使用static静态变量了。
作用:
stringp为指向欲分割的字符串,delim为分隔符,函数将返回分隔符前面的字符串,stringp将指向分隔符之后的字符串。
Be cautious when using this function. If you do use it, note that:
This function modifies its first argument.
This function cannot be used on constant strings.
The identity of the delimiting character is lost.
strtok, strtok_r - extract tokens from strings
#include <string.h>char *strtok(char *str, const char *delim); //会修改数据源。外部加锁才线程安全(strtok执行结束再解锁执行另一个strtok循环知道工作完成) char *strtok_r(char *str, const char *delim, char **saveptr);
代码示例:*
#include <string.h> #include <stdio.h> int main(int arg, const char *argv[]) {/*字符串不能为常量*/ char* string = strdup("/home/yinlijun/project:/home/yinlijun:/home/someone");char* p;while((p = strsep(&string, ":")) != NULL) /*第一个参数设为二级指针,字符串中所有的第二个参数(子串)最后会被替代成‘/0’*/ { printf("%s/n", p);}free(string); return 0; }
相同点
对该函数的调用序列将str拆分为token,这些token是由作为定界符一部分的任何字符分隔的连续字符的序列。
首次调用时,该函数需要一个C字符串作为str的参数,该字符串的第一个字符用作扫描令牌的起始位置。
在随后的调用中,该函数需要一个空指针,并使用最后一个标记结束后的位置作为扫描的新起始位置。
为了确定token的开头和结尾,该函数首先从起始位置扫描未包含在定界符中的第一个字符(该字符成为token的开头)。
然后从token的开头开始扫描定界符中包含的第一个字符,该字符成为token的末尾。如果找到终止的空字符,扫描也会停止。
token的此结尾将自动替换为空字符(NULL),并且token的开头由函数返回。
一旦在对strtok的调用中找到了str的终止null字符,此函数的所有后续调用(将null指针作为第一个参数)都将返回null指针。
找到下一个标记的点由在下一次调用时使用的函数在内部保留(不需要特殊的库实现来避免数据争用)。
两者都会对原字符串进行修改。
不同点
- strtok内部记录上次调用字符串的位置,所以是不可重入的,不支持多线的,其可重入版本为strtok_r。
- strsep使用传入的参数来确定字符串的起始位置,是可重入的,也是Linux kernel推荐的函数,strtok的替代品。
- strtok()是被标准化(C标准,并因此也通过POSIX),
但strsep()不规范(由C或POSIX;它是GNU C库中可用的,和起源于BSD).因此,可移植的代码strtok()比strsep().更容易使用- strtok()允许在单个标记之间使用多个分隔符,而strsep()期望标记之间使用单个分隔符,并将相邻分隔符解释为空标记.
什么时候使用它们?
- 使用strsep函数,当您需要处理空字段,或者在不同字段之间使用单个分隔符,并且在不介意可移植性的情况下。
- 使用strtok_r函数,当您希望在字段之间允许多个分隔符,不需要处理空字段,并且要求代码具有良好的POSIX兼容性。
- 尽量避免使用strtok函数,因为它是不可重入的,容易导致问题。尤其在多线程环境中,strtok的使用可能导致程序出现不稳定的行为。
您可以strsep()在需要空字段时使用,而不是在字段之间允许多个分隔符,并且在您不介意可移植性时使用.
你会使用strtok_r(),当你想允许标记之间的多个分隔符,你不想空字符(和POSIX足够的便携式你).
strtok()如果你不这样做,你只会在有人威胁你的生命时使用.而你只能用它足够长的时间让你摆脱危及生命的境地; 然后你会再次放弃使用它.它有毒; 不要使用它.编写自己的strtok_r()或者strsep()使用它会更好strtok().
为什么strtok()有毒?
strtok()如果在库函数中使用,该函数是有毒的.如果您的库函数使用strtok(),则必须清楚地记录.
那是因为:
- 如果任何调用函数正在使用strtok()并调用也使用的函数strtok(),则会中断调用函数.
- 如果你的函数调用任何调用的函数strtok(),那将破坏你的函数的使用strtok().
- 如果您的程序是多线程的,那么strtok()在任何给定时间最多只能有一个线程使用- 跨越一系列strtok()调用.
此问题的根源是调用之间保存的状态,允许strtok()在停止的位置继续.除了"不要使用strtok()" 之外,没有合理的方法来解决问题.
- strsep()如果可用,您可以使用.
- 您可以使用POSIX(strtok_r()如果可用).
- strtok_s()如果可用,您可以使用Microsoft .
- 名义上,您可以使用ISO/IEC 9899:2011附件K.3.7.3.1功能strtok_s(),但其界面strtok_r()与微软的界面不同strtok_s()
探索C语言之字符串分割函数:strtok和strsep的区别相关推荐
- 字符串分割函数--strtok与strsep
在c/c++中,字符串分割函数主要有两种:一是strtok函数,另一个就是strsep函数.下面我们对这两个函数作一个详细解释说明. 1.strtok 原形: char* strtok(char *s ...
- 字符串分割函数strtok和strsep使用注意事项
转载自 https://blog.csdn.net/astrotycoon/article/details/50813959 为什么写本文 最近工作中经常需要解析字符串,并且这些字符串都有一个共同的特 ...
- c语言strsep,C/C++ 字符串分割: strtok 与 strsep 函数说明(示例代码)
函数原型: char *strtok(char *s, const char *delim); char *strsep(char **s, const char *delim); 功能:strtok ...
- strtok(), strtok_s() 字符串分割函数
strtok(), strtok_s() 字符串分割函数 //strtok()函数原型/*_Check_return_ _CRT_INSECURE_DEPRECATE(strtok_s) _CRTIM ...
- PHP字符串分割函数explode,strtok,str_spli的用法
PHP字符串函数在PHP网站开发中广泛使用,比如使用PHP字符串函数对字符串分割.截取.匹配.替换等处理.PHP字符串函数对于PHP入门学习者来说必不可少,本文将主要介绍PHP字符串分割函数处理心得, ...
- c语言中字符切割函数split,c 语言 指针 C语言字符串分割函数split实现
c语言也有类似其他语言的split字符串分割函数,就是strtok使用方法如下://用逗号做分隔符,读出内容//char s[] = "123-sldkf-123ls-343434-dfjd ...
- c语言将字符串按空格分割_如何在c++中实现字符串分割函数split详解
前言 在学习c++中string相关基本用法的时候,发现了sstream的istringstream[1]可以将字符串类似于控制台的方式进行输入,而实质上这个行为等同于利用空格将一个字符串进行了分割, ...
- C++中string如何实现字符串分割函数split()——4种方法
如: string str1 = "This is a test"; string str2 = "This-is-a-test"; string str2 = ...
- Split字符串分割函数
非常非常常用的一个函数Split字符串分割函数. Dim myTest myTest = "aaa/bbb/ccc/ddd/eee/fff/ggg"Dim arrTest arrT ...
最新文章
- vue从入门到进阶:指令与事件(二)
- RMSD:通过旋转计算两个分子间的最小rmsd
- 不投降就是成功 --- 我看《新喜剧之王》
- 限制edit只能输入数字
- linux系统性能优化及瓶颈分析
- web.config中httpRunTime的属性(转)
- 智能布线系统,“智”在何方
- mybatis多个foreach_MyBatis中使用foreach完成复杂查询
- 求一个特定函数在定义区间上的值是否都为素数
- C语言符号常量的使用,C语言常量与符号常量
- 京东员工p级别分几级_一文揭秘字节跳动、华为、京东的薪资职级
- PAT甲级 1097
- ios 添加浮动效果_自定义悬浮窗详解(模拟IOS小球拖动,轮盘滑动)
- ET服务器框架——部署与运维笔记(一)
- tp5.1 保利威视 云课堂 三分屏 PC直播DEMO(不适合普通直播)
- 普通带条件查询接口报错 Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError:
- 关于offer、三方协议、福利等就业常识
- 乐酷工作室孙志伟:Testin云测试有广度有深度 省钱省力值得信赖
- phpcms选择文件无法加载插件怎么办_浏览器显示无法加载插件怎么办
- 侧边栏固定定位到版心两侧