strtok函数的使用注意事项

2024-05-26 22:48

本文主要是介绍strtok函数的使用注意事项,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录(?)[+]

strtok函数的使用注意事项


1. 函数原型及其基本应用


    strtok函数是用来分解字符串的,其原型是:

[cpp]  view plain copy
  1. char *strtok(char str[], const char *delim);  

    其中str是要分解的字符串,delim是字符串中用来分解的字符,该函数返回分解后的字符串的起始位置指针。之所以是分解,就是说并没有生成新的字符串,只是在源字符串上面做了一些手脚,使得源字符串发生了变化,所以一定要注意,源字符串发生了变化!!!

    先从最简单的应用来看,看下面的例1。

[cpp]  view plain copy
  1. // 例1  
  2. #include <string.h>  
  3.   
  4. void main()  
  5. {    
  6.     char s[] = "192.168.0.26";    
  7.     char *delim = ".";    
  8.     char *p;    
  9.     printf("%s ", strtok(s, delim));    
  10.   
  11.     while((p = strtok(NULL, delim)))      
  12.         printf("%s ", p);     
  13.   
  14.     printf("\n");  
  15. }  

    从例1中就可以看出strtok函数的基本使用方法,输入一个字符串数组,然后就可以将其按照一定的分隔符(例1中为".")将一个长的字符串分割成一个个短的字符串。这里需要注意的是,在对一个长字符串分割的时候,第一次调用时,strtok函数的第一个参数传入要分割的字符串,而第二次以及后面再次调用该函数的时候,strtok函数的第一个参数应该传入NULL,这是因为在strtok第一个参数为NULL的时候,该函数默认使用上一次未分割完的字符串的未分割的起始位置作为本次分割的起始位置,直到分割结束为止。

    这个例子就最常见的基本应用,但是仅仅知道这些很容易忽略很多细节问题,后面本文将继续讨论一些值得注意的问题。

2. 使用注意事项1


    这里首先需要强调的是strtok函数在进行字符串分解的时候,其第一个参数,即char str[]是在变化的,就像前面说过的一样,其只是对源字符串动了一些手脚,也就是改变了源字符串。以例1中的字符串来说,"192.168.0.26"是源字符串,在调用strtok对其分解结束后,字符串变成了"19201680026",注意其中红色加粗部分是把'.'替换成了'\0',也就是替换成了字符串结束标志字符,这样在打印或使用的时候都会使得前面的字符串成为一个看起来独立的字符串,即"192"、"168"、"0"、"26",这些字符串还是在源字符串中,只是后面都有了自己的字符串结束标志'\0'而已。

3. 使用注意事项2


    在注意事项1中提到了源字符串发生了变化,同时注意到strtok函数原型的第一个参数是一个字符数组char str[],虽然说传递参数时实参可以是一个指针,但是这个指针如果是字符串常量指针,那么就会引起程序运行时崩溃,因为源字符串要发生变化,而字符串常量是不能被改变的,例如下面的例2就是错误的。

[cpp]  view plain copy
  1. // 例2  
  2. #include <string.h>  
  3.   
  4. void main()  
  5. {    
  6.     char *s = "192.168.0.26";  // 与例1的唯一区别,字符串数组变成了字符串常量指针!!!  
  7.     char *delim = ".";    
  8.     char *p;    
  9.     printf("%s ", strtok(s, delim));    
  10.   
  11.     while((p = strtok(NULL, delim)))      
  12.         printf("%s ", p);     
  13.   
  14.     printf("\n");  
  15. }  

    所以如果输入是字符串常量指针的时候,是不能直接传递给strtok函数的第一个参数的,大家可以将这个字符串常量指针中的内容逐一拷贝到一个字符串数组中,再进行分解,不过这种方法效率比较低,所以并不建议这样使用,如果实在无法使用strtok函数进行字符串分解,那么可以使用其他的函数进行类似分解,比如使用strstr函数、strchr函数等。

4. 使用注意事项3


    对于strtok函数的第二个参数,即分隔符,要注意:包含在delim中的字符均可以作为分隔符,而非严格匹配。可以把delim理解为分隔符的集合。这一点是非常重要的!当然,我们在分解字符串的时候,很少使用多个分隔符。这也导致,很多人在写例子的时候只讨论了一个分隔符的情况。有更多的人在看例子的时候也就错误的认识了delim的作用。    

5. 使用注意事项4


    如果strtok函数要分解的字符串的首字符就是分隔符,那么strtok函数会忽略第一个字符,直接从下一个分隔符算起。比如:".192.168.0.26",那么第一个字符'.'就会被忽略,分解后的第一个字符串就是"192"。

    总之,strtok函数是一个看起来很简单,但是使用起来有很多需要注意的细节的函数,所以应该理解掌握,由于strtok函数并不是线程安全的,所以很多情况下并不再使用这个函数,而是由程序员实现自己的字符串分割函数,从而保证线程安全,不过,在Linux中定义了strtok_r函数,这个函数是strtok函数的线程安全版本,具体使用方法可以参考其他资料。

    如果大家还有别的意见,欢迎大家多多补充,谢谢。

    参考资料:

http://blog.csdn.net/helpxs/article/details/6958975

这篇关于strtok函数的使用注意事项的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1005801

相关文章

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有

MyBatis ParameterHandler的具体使用

《MyBatisParameterHandler的具体使用》本文主要介绍了MyBatisParameterHandler的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一、概述二、源码1 关键属性2.setParameters3.TypeHandler1.TypeHa