字符串分割的问题
来源:互联网 发布:电脑端口怎么设置 编辑:程序博客网 时间:2024/06/10 06:02
一、用strtok函数进行字符串分割
原型: char *strtok(char *str, const char *delim);
功能:分解字符串为一组字符串。
参数说明:str为要分解的字符串,delim为分隔符字符串。
返回值:返回指向第一段被截取出来的字符串的指针(根据 delim 内的字符进行截取). 如果没有找到, 那么就返回 NULL.
调用说明:
(1). 第一次调用 strtok 时, 第一个参数是 strToken, 以后再调用时, 第一个参数必须是 NULL;
(2). 调用 strtok 后, 原字符串会被修改;
(3). strtok 不是一个线程安全的函数.
源代码分析:
从 这里 贴出的 Linux 下的 string.h 的实现可以看出:
(1). strtok 使用一个全局定义的 char * ___strtok; 来指向截取后的剩余字符串, 所以从第二次开始调用 strtok 后, 第一个参数就只需要设为 NULL 就可以了;
(2). strtok 函数会在一开始就判断其第一个参数, 若不为 NULL, 就取其第一个参数进行截取, 并将 ___strtok 指向截取后的字符串; 若为NULL, 则使用 ___strtok 进行截取, 并将 ___strtok 指向截取后的字符串;
(3). strtok 使用 sbegin 指向待截取的字符串, 当找到 strDelimit 里的字符时, 就在这个字符前面插入 '\0', 这样就相当于从 sbegin 指向的字符串里截取出前面一段了. 而后面一段, 则由 ___strtok 指向, 等待下一次截取.
示例:
//借助strtok实现split#include <string.h>#include <stdio.h>int main(){ char s[] = "Golden Global View,disk * desk"; const char *d = " ,*"; char *p; p = strtok(s,d); while(p) { printf("%s\n",p); p=strtok(NULL,d); } return 0;}
二、用STL进行字符串的分割
涉及到string类的两个函数find和substr:
1、find函数
原型:size_t find ( const string& str, size_t pos = 0 ) const;
功能:查找子字符串第一次出现的位置。
参数说明:str为子字符串,pos为初始查找位置。
返回值:找到的话返回第一次出现的位置,否则返回string::npos
2、substr函数
原型:string substr ( size_t pos = 0, size_t n = npos ) const;
功能:获得子字符串。
参数说明:pos为起始位置(默认为0),n为结束位置(默认为npos)
返回值:子字符串
实现如下:
#include <iostream>#include <string>#include <vector>//字符串分割函数std::vector<std::string> split(std::string str,std::string pattern){ std::string::size_type pos; std::vector<std::string> result; str+=pattern;//扩展字符串以方便操作 int size=str.size(); for(int i=0; i<size; i++) { pos=str.find(pattern,i); if(pos<size) { std::string s=str.substr(i,pos-i); result.push_back(s); i=pos+pattern.size()-1; } } return result;}int main(){ std::string str; std::cout<<"Please input str:"<<std::endl; //std::cin>>str; getline(std::cin,str); std::string pattern; std::cout<<"Please input pattern:"<<std::endl; //std::cin>>pattern; getline(std::cin,pattern);//用于获取含空格的字符串 std::vector<std::string> result=split(str,pattern); std::cout<<"The result:"<<std::endl; for(int i=0; i<result.size(); i++) { std::cout<<result[i]<<std::endl; } std::cin.get(); std::cin.get(); return 0;}
三、用Boost进行字符串的分割
用boost库的正则表达式实现字符串分割
实现如下:
//本程序实现的是利用正则表达式对字符串实现分割//运行环境 VC6.0 + boost 库#include <iostream>#include <cassert>#include <vector>#include <string>#include "boost/regex.hpp"std::vector<std::string> split(std::string str,std::string s){ boost::regex reg(s.c_str()); std::vector<std::string> vec; boost::sregex_token_iterator it(str.begin(),str.end(),reg,-1); boost::sregex_token_iterator end; while(it!=end) { vec.push_back(*it++); } return vec;}int main(){ std::string str,s; str="sss/ddd/ggg/hh"; s="/"; std::vector<std::string> vec=split(str,s); for(int i=0,size=vec.size();i<size;i++) { std::cout<<vec[i]<<std::endl; } std::cin.get(); std::cin.get(); return 0;}
boost里面有自带的split的函数,如果用boost的话,还是直接用split的好,这里就不多说了,代码如下:
#include <iostream>#include <string>#include <vector>#include <boost/algorithm/string/classification.hpp>#include <boost/algorithm/string/split.hpp> using namespace std; int main(){ string s = "sss/ddd,ggg"; vector<string> vStr; boost::split( vStr, s, boost::is_any_of( ",/" ), boost::token_compress_on ); for( vector<string>::iterator it = vStr.begin(); it != vStr.end(); ++ it ) cout << *it << endl; return 0;}
四、以下是c实现的字符串分割
1.
/* Function: split() * * Purpose: Splits a string into tokens non-destructively. * * Parameters: * char *str => the string to be split * char *sep => a string of token seperaters * int max_strs => how many tokens should be returned * int *toks => place to store the number of tokens found in str * char meta => the "escape metacharacter", treat the character * after this character as a literal and "escape" a * seperator * * Returns: * 2D char array with one token per "row" of the returned * array. */static char **split(char *str, char *sep, int max_strs, int *toks, char meta){ char **retstr; /* 2D array which is returned to caller */ char *idx; /* index pointer into str */ char *end; /* ptr to end of str */ char *sep_end; /* ptr to end of seperator string */ char *sep_idx; /* index ptr into seperator string */ int len = 0; /* length of current token string */ int curr_str = 0; /* current index into the 2D return array */ char last_char = (char) 0xFF; if(!toks) return NULL; *toks = 0; if (!str) return NULL; /* * find the ends of the respective passed strings so our while() loops * know where to stop */ sep_end = sep + strlen(sep); end = str + strlen(str); /* remove trailing whitespace */ while(isspace((int) *(end - 1)) && ((end - 1) >= str)) *(--end) = '\0'; /* -1 because of NULL */ /* set our indexing pointers */ sep_idx = sep; idx = str; /* * alloc space for the return string, this is where the pointers to the * tokens will be stored */ if((retstr = (char **) malloc((sizeof(char **) * max_strs))) == NULL) return NULL; max_strs--; /* loop thru each letter in the string being tokenized */ while(idx < end) { /* loop thru each seperator string char */ while(sep_idx < sep_end) { /* * if the current string-indexed char matches the current * seperator char... */ if((*idx == *sep_idx) && (last_char != meta)) { /* if there's something to store... */ if(len > 0) { if(curr_str <= max_strs) { /* allocate space for the new token */ if((retstr[curr_str] = (char *) malloc((sizeof(char) * len) + 1)) == NULL) { return NULL; } /* copy the token into the return string array */ memcpy(retstr[curr_str], (idx - len), len); retstr[curr_str][len] = 0; /* twiddle the necessary pointers and vars */ len = 0; curr_str++; last_char = *idx; idx++; } /* * if we've gotten all the tokens requested, return the * list */ if(curr_str >= max_strs) { while(isspace((int) *idx)) idx++; len = end - idx; fflush(stdout); if((retstr[curr_str] = (char *) malloc((sizeof(char) * len) + 1)) == NULL) return NULL; memcpy(retstr[curr_str], idx, len); retstr[curr_str][len] = 0; *toks = curr_str + 1; return retstr; } } else /* * otherwise, the previous char was a seperator as well, * and we should just continue */ { last_char = *idx; idx++; /* make sure to reset this so we test all the sep. chars */ sep_idx = sep; len = 0; } } else { /* go to the next seperator */ sep_idx++; } } sep_idx = sep; len++; last_char = *idx; idx++; } /* put the last string into the list */ if(len > 0) { if((retstr[curr_str] = (char *) malloc((sizeof(char) * len) + 1)) == NULL) return NULL; memcpy(retstr[curr_str], (idx - len), len); retstr[curr_str][len] = 0; *toks = curr_str + 1; } /* return the token list */ return retstr;}/**************************************************************** * * Free the buffer allocated by split(). * * char** toks = NULL; * int num_toks = 0; * toks = (str, " ", 2, &num_toks, 0); * split_free(&toks, num_toks); * * At this point, toks is again NULL. * ****************************************************************/static void split_free(char ***pbuf, int num_toks){ int i; char** buf; /* array of string pointers */ if( pbuf==NULL || *pbuf==NULL ) { return; } buf = *pbuf; for( i=0; i<num_toks; i++ ) { if( buf[i] != NULL ) { free( buf[i] ); buf[i] = NULL; } } free(buf); *pbuf = NULL;}2.
//gcc split.c -o split /* * 系统环境:Linux 或者windows * 编译: gcc 或者vc++ 6.0 * 运行: ./split * ---------------------------------------------------------------------------------------------------- * 实现根据分隔符分隔字符串 *---------------------------------------------------------------------------------------------------- */ #include<stdlib.h> #include<stdio.h> #include<string.h> /* * ---------------------------------------------------------------------------------------------------- * 实现根据分隔符分隔字符串 * @param src:要分隔的字符串 * @param delim:分隔符 * @return 若是src或者delim为空时:返回一个字符串数组指针,以空字符串结尾, 若是无法申请内存:返回NULL, 分隔正常:返回一个字符串数组指针,以空字符串结尾 *---------------------------------------------------------------------------------------------------- */ char **split(const char *src,const char *delim); int main() { char str[]=" ab cd e fghi kn "; char *delim=" "; //分隔符 char **result=NULL; //定义一个字符串数组指针 char **p=NULL; result=split(str,delim); p=result; while(*p[0]){ //为空字符串时退出循环 printf("[%s]\n",*p); free(*p); //释放字符串 p++; } free(*p); free(result); } char **split(const char *src,const char *delim) { int size_char_p=sizeof(char*); char **result=(char**)malloc(size_char_p); char **ptmp=NULL; //用来记录新扩大的内存地址 char *src_copy; int index=0; //申请的字符串指针索引 int result_size=1; //申请的字符串指针个数 int i=0; char *p; if(src==NULL||delim==NULL){ *result=strdup(""); return result; } //备份源字符串 src_copy=strdup(src); //开始分隔第一个字符串 p=strtok(src_copy,delim); //全部为空,或者空格 if(p==NULL||strlen(p)==0) { //释放备份 free(src_copy); *result=strdup(""); return result; } //重新申请字符串指针空间 ptmp=(char**)realloc(result,(++result_size)*size_char_p); if(ptmp==NULL){ printf("cannot realloc\n"); free(result); return NULL; } result=ptmp; *result=strdup(p); index++; //重新申请字符串指针的空间 while((p=strtok(NULL,delim))) { if(*p=='\0'){ continue; } //重新申请字符串指针 ptmp=(char**)realloc(result,(++result_size)*size_char_p); if(ptmp==NULL){ printf("cannot realloc\n"); //无法申请内存,则释放申请的空间 for(i=0;i<result_size;i++){ free(result[i]); } free(result); return NULL; } result=ptmp; result[index]=strdup(p); index++; } //释放备份字符串 free(src_copy); //把最后一个置为空 result[index]=strdup(""); return result; }
3.可以分割“,”和",“ ”分开的字符窜
/* *function 分割.csv格式的文本文件中的字符串,即用","和",""分开的字符串 *@param str 要分割的字符串 *@param arr 存储分割之后的各个字符串 *@param siz 把str分割成子字符串的个数 */int csvsplit(char *str, char **arr, int siz){ char *ptr, *end, *left, *right; int num; ptr = str; num = 0; while ( ( *ptr != '"' && NULL != (end = strchr(ptr, ',')) ) || ( *ptr == '"' && NULL != (end = strstr(ptr, "\",")) ) ) { if (*ptr == '"') end++; *end = '\0'; arr[num++] = ptr; ptr = end + 1; if (num >= siz) return num; } arr[num++] = ptr; return num;}
4.
[C语言]字符串处理 - 以指定的字符串分割字符串(支持中文字符)2008-11-8: 函数StringSplit(分割字符串到一个字符串数组中,其中该数组第0位为分割后字符串的个数)2008-11-10: 函数StringSplit_Struct(以定义一个新结构的方式来实现该函数)/*C代码如下*/#include <stdio.h>/*实现方案1*//*分割字符串到一个字符串数组中,其中该数组第一位为分割后的个数*/char** StringSplit(const char* string,const char* split){ char** result; /*首先分配一个char*的内存,然后再动态分配剩下的内存*/ result = (char * * )malloc(sizeof(char *)*1); memset(result,0,sizeof(char *)*1); /*定义一个遍历用的指针和一个寻找位置用的指针*/ char* p = string; char* pos = string; /*无论是否存在该分割串,绝对都会分割到一个字符串*/ int count = 1; while(*p != '\0') { char* temp; char* tt; /*查找该字符串*/ pos = strstr(p,split); /*结果为0说明剩下的字符串中没有该字符了*/ if(pos == 0) { result = (char * * )realloc(result,sizeof(char *)*(count+2)); result[0] = count; result[count] = p; result[count+1] = NULL; return result; } /*分配临时字符串空间*/ temp = (char * )malloc(sizeof(char)*(pos - p+1)); memset(temp,0,sizeof(char)*(pos - p+1)); /*设置头指针,以便赋值时使用*/ tt = temp; while(p<=pos) { *temp++ = *p++; } /*将字符串结尾置零*/ *--temp = '\0'; result = (char * * )realloc(result,sizeof(char *)*(count+1)); result[0] = count; result[count] = tt; count++; /*设置下一次遍历时的指针(重要)。当split长度大于1时,不这样设置会多赋值不必要的字符串*/ p +=strlen(split)-1; } return result;}/*实现方案2*//*为方便计数定义的结构,字符串数组从0开始赋值*/typedef struct{ int number; /*分割的字符串个数*/ char** string; /*字符串数组*/}StringTab;/*分割字符串到一个字符串数组中*/StringTab StringSplit_Struct(const char* string,const char* split){ StringTab result; /*首先分配一个char*的内存,然后再动态分配剩下的内存*/ result.string = (char * * )malloc(sizeof(char *)*1); memset(result.string,0,sizeof(char *)*1); /*无论是否存在该分割串,绝对都会分割到一个字符串*/ result.number = 0; /*定义一个遍历用的指针和一个寻找位置用的指针*/ char* p = string; char* pos = string; while(*p != '\0') { char* temp; char* tt; /*查找该字符串*/ pos = strstr(p,split); /*结果为0说明剩下的字符串中没有该字符了*/ if(pos == 0) { result.string = (char * * )realloc(result.string,sizeof(char *)*(result.number+1)); result.string[result.number] = p; return result; } /*分配临时字符串空间*/ temp = (char * )malloc(sizeof(char)*(pos - p+1)); memset(temp,0,sizeof(char)*(pos - p+1)); /*设置头指针,以便赋值时使用*/ tt = temp; while(p<=pos) { *temp++ = *p++; } /*将字符串结尾置零*/ *--temp = '\0'; result.string = (char * * )realloc(result.string,sizeof(char *)*(result.number+1)); result.string[result.number] = tt; /*计数器加一*/ result.number++; /*设置下一次遍历时的指针(重要)。当split长度大于1时,不这样设置会多赋值不必要的字符串*/ p +=strlen(split)-1; } return result;}int main(){ /*进行测试*/ /*方案1测试*/ char** array; array = StringSplit("a/aaa//哈aa","aaa"); int i ; for(i=1;i<=(int)array[0];i++) { printf("Num:%d I:%d: Value: %s\n",array[0],i,array[i]); } array = StringSplit("a/aa哈a//哈aa","哈"); for(i=1;i<=(int)array[0];i++) { printf("Num:%d I:%d: Value: %s\n",array[0],i,array[i]); } /*方案2测试*/ StringTab array2; array2 = StringSplit_Struct("a/aaa//哈aa","aaa"); for(i=0;i<=array2.number;i++) { printf("Num:%d I:%d: Value: %s\n",array2.number,i,array2.string[i]); } array2 = StringSplit_Struct("a/aa哈a//哈aa","哈"); for(i=0;i<=array2.number;i++) { printf("Num:%d I:%d: Value: %s\n",array2.number,i,array2.string[i]); } return 0;}
- 字符串分割的问题
- 关于字符串分割的问题
- 有关字符串分割的问题(正则表达式)
- split分割字符串遇到的问题
- java 竖线分割字符串的问题
- java 竖线分割字符串的问题
- C++ 分割字符串的问题不少啊
- java 竖线分割字符串的问题
- java 竖线分割字符串的问题
- java 竖线分割字符串的问题
- 关于字符串分割问题
- java字符串分割问题
- 字符串分割问题详解
- 字符串分割问题
- mysql如何进行以, -,.分割的字符串的拆分,解决数字字符串分割问题
- 分割字符串的sql
- 字符串的分割方法
- 分割字符串的方法
- .Net使用HttpWebRequest构造POST请求(带文件)_备忘
- 第一篇技术贴(Android WebView)
- Virtualbox Usage
- [读书笔记]CIO Comprehensive Practice - Chapter2
- 编译android源码遇到问题与解决方法
- 字符串分割的问题
- ORA-12545
- 汕习笔痛约亓瞧怨智淄
- HttpURLConnection学习
- MonoDevelop使用中文注释解决方案
- Ubuntu上NFS的安装配置
- MacOS Lion编译安装GCC-4.6.2
- jxl的excel读取
- java 串行化