首页
社区
课程
招聘
[原创]Accelerated+C+++中文版Split 的2个小问题
发表于: 2014-3-16 17:11 5841

[原创]Accelerated+C+++中文版Split 的2个小问题

2014-3-16 17:11
5841
Accelerated C+++中文版Split 的2个小问题
                        (253732597@qq.com tonybo@gmail.com )

第一个:
中文版的这句 while(j!=s.size() && s[i]!=sep) 中的i应该是j,所以正确的语句应该是 while(j!=s.size() && s[j]!=sep),英文版的是没问题的。

第二个:
第二个就是当源字符串中有连续的分隔符的时候就劈得不正确了,下面是测试代码和结果。

#include<vector>
#include<string>
#include<algorithm>
#include<iostream>

using namespace std;

vector<string> split(const string& s, char sep){

        typedef string::size_type string_size;
        vector<string> ret;
        string_size i=0;

       
        while(i !=s.size()){
                while(i!=s.size() && s[i]==sep)
                        ++i;
                string_size j=i;

                while(j!=s.size() && s[j]!=sep)
                        ++j;

                if(i!=j){
                        ret.push_back(s.substr(i,j-i));
                        i=j;
                }
        }
        return ret;
}

int main(){

        string test_str="2B3A245D32-D01,09/23/13,07:52:31 AM,12:00:25 AM,R302F2,2.5-B6-01124,C:\\RenoData\\PDC New Master\\,240,M,BTSE00,332,NW16A,N/A,,,Pass,,0,A3,93915,1,ID,1001,PDC,0,513.14,0,0,0,0,101.4,178.43,1009,1,1,15.98,258.21,0.9,3.73,60.33,57.88,15.22,251.13,8.81,150,16.16,59.73,-2.95,-2.05,-5.45,39.99,34.54,-4.26,-3.63E-002,-0.7,-5.07,-4.59,-4.92,-4.35,-4.92,-4.81,-4.7,-5.1,-4.7,-5.09,-4.95";

        string test_str1="SN,Date,Time,TestTime,FixtureNum,BoardID,ProjPath,TBG,Marking,LotNumber,HeadPerMedia,MediaNum,LoaderNum,HOLDER_NO,SpecRevision,Pass/Fail,FirstFail,ErrorCode,Grade,Track,ZoneNum,Zone,SetupID,SetupName,Head,MRR(Ohm),AbsRMS,MCFaultCode,RelRMS,ZAPRate,MRW,MWW,Offset,RSQ_L,RSQ_R,12T_HGA_TAA(mV),12T_TAA(mV),DTAA_Asym2(%),HF_HGA_TAA(mV),HF_TAA(mV),HGA_Resolution(%),LF_HGA_TAA(mV),LF_TAA(mV),MF_HGA_TAA(mV),MF_TAA(mV),PreampGain(V/V),Resolution(%),TAA_Asym(%),TAA_Asym2(%),DeltaOW(dB),OVWR_H(dB),OVWR_L(dB),ATE_BER,Delta2BER,DeltaBER,FinalBER_0,FinalBER+1,FinalBER+2,FinalBER-1,FinalBER-2,InitBER_0,InitBER+1,InitBER+2,InitBER-1,InitBER-2,MedianBER";

        vector<string> v=split(test_str,',');

        for(vector<string>::size_type i=0;i!=v.size();++i)
                cout<<v[i]<<" ";
       
        cout<<endl;
        vector<string> v1=split(test_str1,',');
        for(vector<string>::size_type i=0;i!=v1.size();++i)
                cout<<v1[i]<<" ";
       
        cout<<endl<<v.size();
        cout<<endl<<v1.size();
}

运行结果:

你可以看出两个字符串劈出来的个数不一样(图片中红线hightlight 的地方)。

不正确的后果就是你接着引用劈出来的结果就会产生莫名其妙的结果,我调试了很久才发现问题出现在split函数上。

下面我自己用C写了个split,解决了上面说的问题,就是用空串代替那种连续的分隔,其他的bug还没发现。

代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int split(char *src,char *outstr[],char sep){

                int i=0,j=0,k=0;
                char *p;
                while(i!=strlen(src)){
                        while(i!=strlen(src) && src[i]==sep){
                                if(src[i+1]==sep)
                                        break;
                                else
                                        ++i;
                        }
                       
                        j=i;

                        if(src[j+1]==sep)
                                ++j;

                        while(j!=strlen(src) && src[j]!=sep)
                                        ++j;
                       

                        if(i!=j){
                               
                                p=malloc((j-i+1)*sizeof(char));
                                memcpy(p,&src[i],j-i);
                                p[j-i]='\0';
                                outstr[k++]=p;
                                i=j;
                               
                        }
                }
                return k;
}

void free_str(char *a[],int k){

        char *p;
        int i;
        for(i=0;i<=k;i++){
               
                free(a[i]);
       
        }
       
}

int main(){

                char *test_str="2B3A245D32-D01,09/23/13,07:52:31 AM,12:00:25 AM,R302F2,2.5-B6-01124,C:\\RenoData\\PDC New Master\\,240,M,BTSE00,332,NW16A,N/A,,,Pass,,0,A3,93915,1,ID,1001,PDC,0,513.14,0,0,0,0,101.4,178.43,1009,1,1,15.98,258.21,0.9,3.73,60.33,57.88,15.22,251.13,8.81,150,16.16,59.73,-2.95,-2.05,-5.45,39.99,34.54,-4.26,-3.63E-002,-0.7,-5.07,-4.59,-4.92,-4.35,-4.92,-4.81,-4.7,-5.1,-4.7,-5.09,-4.95";
                char *test_str1="SN,Date,Time,TestTime,FixtureNum,BoardID,ProjPath,TBG,Marking,LotNumber,HeadPerMedia,MediaNum,LoaderNum,HOLDER_NO,SpecRevision,Pass/Fail,FirstFail,ErrorCode,Grade,Track,ZoneNum,Zone,SetupID,SetupName,Head,MRR(Ohm),AbsRMS,MCFaultCode,RelRMS,ZAPRate,MRW,MWW,Offset,RSQ_L,RSQ_R,12T_HGA_TAA(mV),12T_TAA(mV),DTAA_Asym2(%),HF_HGA_TAA(mV),HF_TAA(mV),HGA_Resolution(%),LF_HGA_TAA(mV),LF_TAA(mV),MF_HGA_TAA(mV),MF_TAA(mV),PreampGain(V/V),Resolution(%),TAA_Asym(%),TAA_Asym2(%),DeltaOW(dB),OVWR_H(dB),OVWR_L(dB),ATE_BER,Delta2BER,DeltaBER,FinalBER_0,FinalBER+1,FinalBER+2,FinalBER-1,FinalBER-2,InitBER_0,InitBER+1,InitBER+2,InitBER-1,InitBER-2,MedianBER";

                char *re[256];
                char *result[256];
                int c,i;
                c=split(test_str,re,',');
                printf("%d\n",c);

                for(i=0;i<c;i++)
                        printf("%s ",re[i]);
                printf("\n");

                free_str(re,c);

                c=split(test_str1,result,',');
                printf("%d\n",c);
                for(i=0;i<c;i++)
                        printf("%s ",result[i]);
                printf("\n");

                free_str(result,c);
}
下面是结果:

代码写的有点乱,就不多解释了,实在看不了就调试一下吧,C++版本的就自己照着C版本的改一下吧,或者用更好的库吧,再不行就自己写个最好的,split在CSV文件中很有用,C/C++标准库里面好像没有,所以就自己参考了一下书上写了一个。(完)。

[课程]Linux pwn 探索篇!

上传的附件:
收藏
免费 5
支持
分享
最新回复 (2)
雪    币: 19
活跃值: (74)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
mark一下,正在看这个,感觉比c++ primer能看的进去。
2014-3-22 09:28
0
雪    币: 285
活跃值: (113)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
恩,同感。
2014-3-22 13:10
0
游客
登录 | 注册 方可回帖
返回
//