在python中,假设要求当前时间的unix时间戳,我特别喜欢这么用:

import time
timestr = time.time()
timestamp = int(timestr.split('.')[0])

这里的split函数,我非常喜欢,在java、c#和python中都有,非常方便,不用操心踩地雷,可是C/CPP中,就没有了,这点比較遗憾。

假设要处理一个字符串型的“192.168.1.254”,想把每一个字段都分开,怎么办呢,C标准库中有函数strtok()的实现,能够一用。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>int main()
{char ip_str[] = "192.168.1.250";char *ip_arr[4] ;char * s = strtok(ip_str, ".");int i=0;while(s){ip_arr[i] = s;s = strtok(NULL, ".");i++;
//      printf("%s\n",s);}for(i=0; i<4; i++)printf("%s\n",ip_arr[i]);
}

在这里,strtok是非线程安全的,这点也能够在程序的第二次strtok调用中看到,因此linux用strsep来替换strtok了,我在linux2.6.22的源代码/lib/string.c和linux-3.3中同文件里,c文件开头就是这样一段话:

/**  linux/lib/string.c**  Copyright (C) 1991, 1992  Linus Torvalds*//** stupid library routines.. The optimized versions should generally be found* as inline code in <asm-xx/string.h>** These are buggy as well..** * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>* -  Added strsep() which will replace strtok() soon (because strsep() is*    reentrant and should be faster). Use only strsep() in new code, please.** * Sat Feb 09 2002, Jason Thomas <jason@topic.com.au>,*                    Matthew Hawkins <matt@mh.dropbear.id.au>* -  Kissed strtok() goodbye*/

由于strsep是线程安全的,并且速度上更快一些,所以採用strsep来替换strtok,接下来我会试一试strsep。在这里感慨下,没事的时候或者敲代码的时候,用man和查看源代码的方式,能学到非常多主要的知识,比方内核源代码的lib目录下,linux内核使用的rbtree结构,还有lib目录的string.c,include下的string.h里的各种strcpy,strcat等基本函数的实现,都是非常经典并且久经考验的。

在strtok使用的代码里,有两处非常有意思。

当中一个,改动第7行,例如以下所看到的:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>int main()
{char *ip_str = "192.168.1.250";char *ip_arr[4] ;char * s = strtok(ip_str, ".");int i=0;while(s){ip_arr[i] = s;s = strtok(NULL, ".");i++;
//      printf("%s\n",s);}for(i=0; i<4; i++)printf("%s\n",ip_arr[i]);
}

将char ip_str[] = "192.168.1.250";改为char *ip_str = "192.168.1.250";就会core dump,通过gdb和core文件来看,程序崩溃在了

Program terminated with signal 11, Segmentation fault.
#0  strtok () at ../sysdeps/i386/i686/strtok.S:245
245      movb $0, (%edx) /* Terminate string.  */
(gdb) where
#0  strtok () at ../sysdeps/i386/i686/strtok.S:245
#1  0x0804841e in main () at test.c:9

而这段代码在VS下是没有问题的,所以这个原因须要找一下。

这个原因找到了,在链接http://www.cnblogs.com/longzhao1234/archive/2012/05/31/2528317.html

通过阅读源码,由于函数内部会改动原字符串变量,所以传入的參数不能是不可变字符串(即文字常量区)。
如 char *tokenremain ="abcdefghij"//编译时为文字常量,不可改动。
strtok(tokenremain,"cde");
strsep(&tokenremain,"cde");
编译通过,执行时会报段错误。

VS在非常多情况下要比GCC优秀非常多,VS的CPP支持是最全面的,能够这么说。好多CPP的作者啦,大牛啦,都是M$的VC组的,好牛逼的地方。

另外在改一处,这次仅仅改第16行,将printf语句凝视掉,代码例如以下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>int main()
{char ip_str[] = "192.168.1.250";char *ip_arr[4] ;char * s = strtok(ip_str, ".");int i=0;while(s){ip_arr[i] = s;s = strtok(NULL, ".");i++;printf("%s\n",s);}for(i=0; i<4; i++)printf("%s\n",ip_arr[i]);
}

又崩溃了,我也整个人都不好了。

分析core文件,出错例如以下:

Program terminated with signal 11, Segmentation fault.
#0  __strlen_ia32 () at ../sysdeps/i386/i586/strlen.S:99
99   movl (%eax), %ecx /* get word (= 4 bytes) in question */
(gdb) where
#0  __strlen_ia32 () at ../sysdeps/i386/i586/strlen.S:99
#1  0x00b9ddd5 in _IO_puts (str=0x0) at ioputs.c:37
#2  0x0804846b in main () at test.c:16

令人欣慰的是,VS在这句也崩了。

依据core文件的提示,在#0处,在strlen函数这里崩溃了,我推断,是strtok阶段字符数组到最后,要在printf("%s\n",s);处打印时,因为没有'\0'符号,所以缓冲区无法截断,最后溢出导致printf崩溃,所以我又一次声明一个长度为sizeof(ip_str)+1的字符数组,将ip_str复制进去,并将最后一个字符置为'\0',代表字符结束,结果依旧崩溃。

假设我把printf("%s\n",s);改为printf("%s\t",s);,由于printf是打印到标准输出中,而标准输出是行缓冲的,对于'\n',代表行缓冲结束,须要输出,假设我不让他输出,会如何?

打印结果为:

168    1   250 (null)  

好吧我也不知道是什么了,并且这个结果与是否有'\0'符号无关。

这两个地方一定要找出来问题,嗯。

接下来我们看看strsep的使用方法吧

#include<stdio.h>
#include<stdlib.h>
#include<string.h>int main()
{char ip_str[] = "192.168.1.250";char *p = ip_str;char *ip_arr[4] ;char * s = strsep(&p, ".");int i=0;while(s){ip_arr[i] = s;s = strsep(&p, ".");i++;
//      printf("%s\n",s);}for(i=0; i<4; i++)printf("%s\n",ip_arr[i]);
}

使用方法也差点儿相同。

转载于:https://www.cnblogs.com/mengfanrong/p/4254076.html

c/cpp中怎样切割字符串,相似于split的功能相关推荐

  1. Java字符串分割方法split()的功能以及使用方法的详细介绍!

    在Java的学习中经常会遇到按照自己的理想情况分割字符串,并根据分割后的结果进行后续操作的问题.对于这些问题就可以使用Java提供的split() 方法进而实现,下面详细的介绍它的功能以及使用方法. ...

  2. c语言将字符串按空格分割_如何在c++中实现字符串分割函数split详解

    前言 在学习c++中string相关基本用法的时候,发现了sstream的istringstream[1]可以将字符串类似于控制台的方式进行输入,而实质上这个行为等同于利用空格将一个字符串进行了分割, ...

  3. C#中切割字符串之正则表达式应用

    这个是我做的使用正则表达式来切割字符串的一个案例部分代码: 功能简介:一条物流信息字符串中截取出多种数据详情 需要切割出的数据包括: 起始地,目的地,货物数量,货物单位,货物类型,车数量,车长度,车类 ...

  4. php截取数组中的字符串,PHP 中使用explode()函数切割字符串为数组的示例

    explode()函数的作用:使用一个字符串分割另一个字符串,打散为数组. 例如: 字符串 PHP;"> $pizza = "第1 第2 第3 第4 第5 第6"; ...

  5. 找出两个字符串中最大子字符串,如abractyeyt,dgdsaeactyey的最大子串为actyet

    // 最大子字符串.cpp : 定义控制台应用程序的入口点. // //找出两个字符串中最大子字符串,如"abractyeyt","dgdsaeactyey"的 ...

  6. 【转】grep搜索子目录中包含某字符串的特定文件

    比如,我想搜源码目录src下,包含"niuc"的所有ec文件 find ./src -name '*.ec' -exec grep -i niuc {} /; -print 在特定 ...

  7. 【Groovy】Groovy 方法调用 ( 字符串切割 | 使用 Java 语法切割字符串 | 使用 Groovy 语法切割字符串直接为变量赋值 | 数组赋值给变量 变量个数小于等于数组长度 )

    文章目录 一.字符串切割 1.使用 Java 语法切割字符串 2.使用 Groovy 语法切割字符串直接为变量赋值 3.数组赋值给变量 变量个数小于等于数组长度 二.完整代码示例 一.字符串切割 在 ...

  8. 按字符串长度切割字符串(支持汉字占2个长度)

    /// <summary> /// 按指定长度切割字符串(汉字算2个字符长度) /// </summary> /// <param name="input&qu ...

  9. grep搜索子目录中包含某字符串的特定文件

    grep -n "str" -r ./ 这是查找当前目录下以及下辖子目录下所有包含str字符串的文件,会列出文件名.以及该行的内容.以及行号  ------------------ ...

  10. 切割 字符串_web前端如何使用字符串

    一.字符串概述 定义:字符串就是用单引号或者双引号包裹起来的,零个或多个排列在一起的字符. 例如:'javascript', "", "345" , '9-11 ...

最新文章

  1. Oracle RAC CSS 超时计算 及 参数 misscount, Disktimeout 说明
  2. 预测分析:R语言实现2.6 特征选择
  3. redis 配置允许其他主机可以远程连接redis
  4. m3u8解析_浅谈m3u8格式视频文件采集
  5. Laravel Facades的实现原理
  6. 背景图片固定(背景图片附着)(HTML、CSS)
  7. JavaScript学习之函数的定义方式及调用
  8. HDU 4278 卡特兰,区间DP
  9. html5兼容包,webpack4搭建现代Hybird-h5工程
  10. 视频直播技术大全、直播架构、技术原理和实现思路方案整理
  11. im2col运算 - 一种卷积优化算法
  12. 无源贴片晶振四角引脚_有源晶振四引脚详细用法
  13. 常见开源规则引擎对比分析
  14. 男女的情事为什么叫走“桃花运”
  15. 10_放置街灯(Placing Lampposts,UVa 10859)
  16. AWE2021:加速拥抱数字化 开启智慧生活新纪元
  17. 线性回归的几种评价方法
  18. 博客营销?软文营销?怎么按照流程走?
  19. beehive 源码阅读- go 语言的自动化机器
  20. Android[游戏,弹力球,弹弹球],自定义[游戏]控件

热门文章

  1. 【网络文件共享】04、rsync基础
  2. 点击类名方法名如何连接到相应的Android源代码
  3. 如何解决安装CentOS时遇到引导分区位于一个GPT分区方案的错误提示问题
  4. Centos单网卡多IP的配置
  5. ubuntu 13.04 web开发从零配置到全装备手记(环境搭建全攻略)
  6. Exchange Server2010系列之五:再谈邮箱基本管理
  7. C/C++程序员面试宝典-2
  8. 如何在linux中也能够使用自动类型推导关键字auto?
  9. Linux内核源码分析--内核启动之(2)Image内核启动(汇编部分)(Linux-3.0 ARMv7)
  10. Linux内核源码分析--内核启动之(1)zImage自解压过程(Linux-3.0 ARMv7)