根据标识符分割字符串

常常遇到根据某个标识符分割字符串,并将分割的结果保存到字符串数组中。遇到过以下几种需求:

  1. 分隔符是一个字符集和,以便处理不同的输入格式,比如用tab或逗号分隔的输入
  2. 处理2个分隔符之间的内容为空的情况,2种需求,输出空字符串或者忽略掉
  3. 处理字符串末尾的回车符,2种需求,忽略或删除

c语言的strtok函数支持分割字符串,它在遇到分隔符之间的内容为空的时候会忽略掉空元素,往前推进返回下个非空的字符串,分割完成后返回NULL。这个函数貌似还有个多线程的版本。



    //分割字符串,如果遇到分割的结果是空字符串也作为输出。  
    
//substr(begin,offset)在begin非法、offset为0或过大的情况返回空字符串  
    void split1(const string& str)  
    {  
        std::vector<string> splitStr;  
      
        char* separator="\t,"
        string::size_type begin=0;  
        string::size_type nextPos;  
        do{     
            nextPos = str.find_first_of(separator,begin); 
            //即使substr返回空字符串也记录  
            splitStr.push_back(str.substr(begin,nextPos-begin));      
            begin = nextPos+1;  
        }while(nextPos != string::npos);  
        //去掉最后的换行符  
        if(splitStr.size()>0){  
            string& lastEle = splitStr.back();  
            if(lastEle.size()>0 && *(lastEle.end()-1)=='\n')  
            {  
                lastEle.erase(lastEle.end()-1);  
            }  
        }  
      
        for(size_t i=0; i < splitStr.size();++i)  
        {  
            printf("case1 idx=%d, len=%d, s=%s\n",i,splitStr[i].size(),splitStr[i].c_str());  
        }  
    }  
    //分割字符串,跳过空字符串。    
    void split2(string& strCellCfg)    
    {    
        std::vector<string> splitStr;    
        char aucTmp[500];    
        strcpy(aucTmp,strCellCfg.c_str());    
        const char* separator = "\t,";    
        //tok函数会跳过“a,,b”分隔符中间的空字符串;且如果找不到被分割的内容,则返回空,比如“,”    
        
//所以以下实现产生的结果中不会包含空字符串    
        char* pToke = strtok(aucTmp,separator);    
        while(pToke!=NULL)    
        {    
            splitStr.push_back(pToke);    
            pToke = strtok(NULL,separator);    
        }    
        if(splitStr.size()>0){    
            string& lastEle = splitStr.back();    
            if(lastEle.size()>0 && *(lastEle.end()-1)=='\n')    
            {    
                lastEle.erase(lastEle.end()-1);    
            }    
        }    
        for(size_t i=0; i < splitStr.size();++i)    
        {    
            printf("case2 idx=%d, len=%d, s=%s\n",i,splitStr[i].size(),splitStr[i].c_str());    
        }    
    }    
    void testSplit()    
    {    
        string t[]={"1,2,3""1 2   3",    
            "h\n",    
            "",    
            ",",    
            ",,",    
            "a,"};    
        for(int i=0; i < 7; ++i)    
        {    
            split1(t[i]);    
            split2(t[i]);    
        }    
    }    

  

 

测试结果:    
case1 idx=0, len=1, s=1    
case1 idx=1, len=1, s=2    
case1 idx=2, len=1, s=3    
case2 idx=0, len=1, s=1    
case2 idx=1, len=1, s=2    
case2 idx=2, len=1, s=3 

   
case1 idx=0, len=1, s=1    
case1 idx=1, len=1, s=2    
case1 idx=2, len=1, s=3    
case2 idx=0, len=1, s=1    
case2 idx=1, len=1, s=2    
case2 idx=2, len=1, s=3  

  
case1 idx=0, len=1, s=h    
case2 idx=0, len=1, s=h    

 

case1 idx=0, len=0, s=    

 

case1 idx=0, len=0, s=  

case1 idx=1, len=0, s=    

 

case1 idx=0, len=0, s=    
case1 idx=1, len=0, s=    
case1 idx=2, len=0, s=    

 

case1 idx=0, len=1, s=a    
case1 idx=1, len=0, s=    
case2 idx=0, len=1, s=a  

 

 

posted @ 2015-03-15 22:51  _pop  阅读(1761)  评论(0编辑  收藏  举报