您的位置:首页 > 其它

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。

例子:

显示的是: 34xyz
#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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: