strtok分割字符串
2015-12-06 15:47
369 查看
sscanf()
- 从一个字符串中读进与指定格式相符的数据。函数原型:
int sscanf( const char *, const char *, ...);
int sscanf(const char *buffer,const char *format,[argument ]...);
buffer存储的数据
format格式控制字符串
argument 选择性设定字符串
sscanf会从buffer里读进数据,依照format的格式将数据写入到argument里。
示例:
sscanf("123-456*abc\ndedf","%d-%d*%s\n%s",int1,int2,buf3,buf4);
Strtok
分解字符串为一组字符串。s为要分解的字符,delim为分隔符字符(如果传入字符串,则传入的字符串中每个字符均为分割符)。首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。原型
编辑char *strtok(char s[], const char *delim);
功能
编辑分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。
例如:strtok("abc,def,ghi",","),最后可以分割成为abc def ghi.尤其在点分十进制的IP中提取应用较多。
说明
编辑strtok()用来将字符串分割成一个个片段。参数s指向欲分割的字符串,参数delim则为分割字符串中包含的所有字符。当strtok()在参数s的字符串中发现参数delim中包含的分割字符时,则会将该字符改为\0
字符。在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。每次调用成功则返回指向被分割出片段的指针。
返回值
编辑从s开头开始的一个个被分割的串。当查找不到delim中的字符时,返回NULL。
所有delim中包含的字符都会被滤掉,并将被滤掉的地方设为一处分割的节点。
示例
官方示例#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char str[]="ab,cd,ef"; char *ptr; printf("before strtok: str=%s\n",str); printf("begin:\n"); ptr = strtok(str, ","); while(ptr != NULL){ printf("str=%s\n",str); printf("ptr=%s\n",ptr); ptr = strtok(NULL, ","); } system("pause"); return 0; }
将字符串按照\n进行分割
// bufferParition.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" int _tmain() { char buffer[] = "turn/ \nDIAMONDS 7 \n/turn \nriver/ \nSPADES A \n/river \nhold/ \nSPADES A \n/hold \n" ; char *ptr; printf("before strtok: str=%s\n",buffer); printf("begin:\n"); const char *strDelimit = "\n"; ptr = strtok(buffer, strDelimit); int i = 0; char bag[10][100]; while(ptr != NULL){ printf("ptr = %s\n",ptr); i++; ptr = strtok(NULL, strDelimit); } system("pause"); return 0; }
另外一个实例,华为软件精英挑战赛2015,中对发送来的消息进行解析的示例。要将字符串进按照turn/ 和/turn这种类型划分。
// strstrTest.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <stdio.h> #include <tchar.h> #include <string.h> int main(int argc,char **argv) { //char a[]="turn/ \nDIAMONDS 7 \n/turn \nriver/ \nSPADES A \n/river \nhold/ \nSPADES A \n/hold \n" ; char a[]="turn/ \nHEARTS 2 \n/turn \nriver/ \nHEARTS 4 \n/river \nshowdown/ \ncommon/ \nDIAMONDS A \nSPADES 10 \nDIAMONDS 3 \nHEARTS 2 \nHEARTS 4 \n/common \n3: 3333 DIAMONDS Q SPADES A ONE_PAIR \n1: 4444 DIAMONDS 5 SPADES J STRAIGHT \n1: 7777 CLUBS 5 HEARTS 7 STRAIGHT \n7: 8888 HEARTS 6 HEARTS 9 HIGH_CARD \n2: 6666 CLUBS 4 CLUBS 10 TWO_PAIR \n6: 5555 CLUBS 8 CLUBS Q HIGH_CARD \n4: 1111 DIAMONDS 10 SPADES 8 ONE_PAIR \n5: 2222 SPADES K CLUBS J HIGH_CARD \n/showdown \npot-win/ \n4444: 8000 \n7777: 8000 \n/pot-win \nseat/ \nbutton: 3333 2000 6000 \nsmall blind: 4444 8000 8000 \nbig blind: 7777 8000 8000 \n8888 2000 6000 \n6666 2000 6000 \n5555 2000 6000 \n1111 2000 6000 \n2222 2000 6000 \n/seat \nblind/ \n4444: 50 \n7777: 100 \n/blind "; printf("原始消息为:%s",a); char *buffer = a; //需要解析的包 char *needle = "\n/"; //分割标识符,但并不是真正的分割处。比如"turn/ \nHEARTS 2 \n/turn \n" //分割处就在\n/后面出现 空格+\n 的后面 char* buf = strstr( buffer, needle); //第一次划分 char message[10][1024]={"\0"}; //存储解析出的信息 int msgLength = 0; //解析出的信息条数 int connectFlag = 0; //仅用于解决showdown消息会不完整的问题, //0表示没有消息合并,1表示有消息需要被合并,2表示已经被合并 while( buf != NULL ) { int i = 0; while (buf[i]!=' ')i++; //找到\n/标识符出现后第一次出现空格的地方 int cut = i+2; //他的后两位就是分割处 buf[cut-1]='\0'; //printf( "Message is :\n%s\n ", buffer); strcpy(message[msgLength],buffer); //将解析出的消息存储到message里,并且加上\n(之前解析造成\n丢失) strcat(message[msgLength],"\n"); //上一段消息不完整,需要与上一段消息合并 if (connectFlag == 1) { strcat(message[msgLength-1],message[msgLength]); msgLength--; connectFlag = 2; //表示已经合并 } //如果消息头为showdown,并且connectFlag的状态不是2,就将connectFlag状态置为1 //表示这段消息以showdown开头,且不完整,需要与下一段消息合并 if (strncmp(message[msgLength],"showdown/ \n",3)==0 && connectFlag != 2 ) { connectFlag = 1; } //memcpy(message[msgLength],buffer,sizeof(buffer)); msgLength++; buffer = buf + cut; buf = strstr( buffer, needle); } printf("一共%d段msg\n",msgLength); for (int j = 0; j<msgLength ;j++) { printf("Message %d:\n%s",j,message[j]); } return 0; }结果如下
原始消息为:turn/ HEARTS 2 /turn river/ HEARTS 4 /river showdown/ common/ DIAMONDS A SPADES 10 DIAMONDS 3 HEARTS 2 HEARTS 4 /common 3: 3333 DIAMONDS Q SPADES A ONE_PAIR 1: 4444 DIAMONDS 5 SPADES J STRAIGHT 1: 7777 CLUBS 5 HEARTS 7 STRAIGHT 7: 8888 HEARTS 6 HEARTS 9 HIGH_CARD 2: 6666 CLUBS 4 CLUBS 10 TWO_PAIR 6: 5555 CLUBS 8 CLUBS Q HIGH_CARD 4: 1111 DIAMONDS 10 SPADES 8 ONE_PAIR 5: 2222 SPADES K CLUBS J HIGH_CARD /showdown pot-win/ 4444: 8000 7777: 8000 /pot-win seat/ button: 3333 2000 6000 small blind: 4444 8000 8000 big blind: 7777 8000 8000 8888 2000 6000 6666 2000 6000 5555 2000 6000 1111 2000 6000 2222 2000 6000 /seat blind/ 4444: 50 7777: 100 /blind 一共6段msg Message 0: turn/ HEARTS 2 /turn Message 1: river/ HEARTS 4 /river Message 2: showdown/ common/ DIAMONDS A SPADES 10 DIAMONDS 3 HEARTS 2 HEARTS 4 /common 3: 3333 DIAMONDS Q SPADES A ONE_PAIR 1: 4444 DIAMONDS 5 SPADES J STRAIGHT 1: 7777 CLUBS 5 HEARTS 7 STRAIGHT 7: 8888 HEARTS 6 HEARTS 9 HIGH_CARD 2: 6666 CLUBS 4 CLUBS 10 TWO_PAIR 6: 5555 CLUBS 8 CLUBS Q HIGH_CARD 4: 1111 DIAMONDS 10 SPADES 8 ONE_PAIR 5: 2222 SPADES K CLUBS J HIGH_CARD /showdown Message 3: pot-win/ 4444: 8000 7777: 8000 /pot-win Message 4: seat/ button: 3333 2000 6000 small blind: 4444 8000 8000 big blind: 7777 8000 8000 8888 2000 6000 6666 2000 6000 5555 2000 6000 1111 2000 6000 2222 2000 6000 /seat Message 5: blind/ 4444: 50 7777: 100 /blind
strstr
strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。str1: 被查找目标 string expression to search.
str2: 要查找对象 The string expression to find.
返回值:若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL。
例子:
#include <string.h> #include <stdio.h> int main(int argc,char **argv){ char a[]="aaa||a||bbb||c||ee||"; char *needle="||"; char *haystack=a;//不能直接char *haystack="aaa||a||bbb||c||ee||"; 会报内存不能写错误 char* buf = strstr( haystack, needle); while( buf != NULL ){ buf[0]='\0';//在出现分隔符的位置设置结束符\0 printf( "%s\n", haystack); haystack = buf + strlen(needle); buf = strstr( haystack, needle); } return 0; } OUT 值: aaa a bbb c ee
相关文章推荐
- psql-05数据库,模式
- Shiro介绍(三):授权及验证的简单之美
- nginx学习(五) http模块
- Magento入门
- scanf的缓冲机制
- hdu 1241 Oil Deposits(DFS)
- POJ 2104 K-th Number(主席树)
- POJ 2761 Feed the dogs(主席树)
- BC65 ZYB's Premutation
- leetcode Maximum Depth of Binary Tree python
- 最重要的重构是内心的重构
- 利用HFS工具进行文件共享
- 有向图强连通分量的Tarjan算法
- Light OJ 1148 - Mad Counting【规律】
- 圆有点挤
- UPC OJ 一道水题 STL
- LeetCode - Two Sum
- C语言中使用extern修饰函数要注意(转)
- Matlab 对字符串的处理
- 数组名与指针