CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
【经验总结】不能实施并行处理的情况 浅谈并行编程中的任务分解模式
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

使用strtok分割字符串,一不小心就容易出现执行到一半内容就被改变的问题,大家一般是用什么办法解决的?

楼主collecte(问题虫)2006-03-08 16:58:51 在 VC/MFC / 基础类 提问

token   =   strtok(   sSoapBuf,   seps   );  
  while(   token   !=   NULL   )  
  {  
  string   tmpStr=&token[7];  
  //   在这里对   tmpStr进行一些操作就可能改变后面取到的token值  
  token   =   strtok(   NULL,   seps   );  
  }  
   
  是不是只能自己写个函数来代替它的功能啊? 问题点数:20、回复次数:3Top

1 楼sterrys(sterrys)回复于 2006-03-08 17:03:02 得分 0

定义另外一个指针,分配内存,把其中一个串拷贝到这个新指针中进行处理Top

2 楼cpio(备注)回复于 2006-03-08 17:03:18 得分 20

标准C++字符串string以及MFC6.0字符串CString的tokenize和split函数。  
   
  1、标准串的:  
   
  /********************************************  
   
      the   tokenize   function   for   std::string  
   
  *********************************************/  
  #include   <string>  
  #include   <vector>  
  #include   <iostream>  
  using   namespace   std;  
   
  typedef   basic_string<char>::size_type   S_T;  
  static   const   S_T   npos   =   -1;  
   
  ////trim指示是否保留空串,默认为保留。  
  vector<string>   tokenize(const   string&   src,   string   tok,     bool   trim=false,   string   null_subst="")  
  {  
    if(   src.empty()   ||   tok.empty()   )   throw   "tokenize:   empty   string\0";  
     
    vector<string>   v;  
    S_T   pre_index   =   0,   index   =   0,   len   =   0;  
    while(   (index   =   src.find_first_of(tok,   pre_index))   !=   npos   )  
    {  
      if(   (len   =   index-pre_index)!=0   )  
        v.push_back(src.substr(pre_index,   len));  
      else   if(trim==false)  
        v.push_back(null_subst);  
      pre_index   =   index+1;  
    }  
    string   endstr   =   src.substr(pre_index);  
    if(   trim==false   )   v.push_back(   endstr.empty()?   null_subst:endstr   );  
    else   if(   !endstr.empty()   )   v.push_back(endstr);  
    return   v;  
  }  
   
  ////使用一个完整的串delimit(而不是其中的某个字符)来分割src串,没有trim选项,即严格分割。  
  vector<string>   split(const   string&   src,   string   delimit,   string   null_subst="")  
  {  
    if(   src.empty()   ||   delimit.empty()   )   throw   "split:   empty   string\0";  
   
    vector<string>   v;  
    S_T   deli_len   =   delimit.size();  
    long   index   =   npos,   last_search_position   =   0;  
    while(   (index=src.find(delimit,   last_search_position))!=npos   )  
    {  
      if(index==last_search_position)  
        v.push_back(null_subst);  
      else  
        v.push_back(   src.substr(last_search_position,   index-last_search_position)   );  
      last_search_position   =   index   +   deli_len;  
    }  
    string   last_one   =   src.substr(last_search_position);  
    v.push_back(   last_one.empty()?   null_subst:last_one   );  
    return   v;  
  }  
   
  //   test  
  int   main(void)  
  {  
    string   src   =   ",ab,cde;,,fg,,"   ;  
    string   tok   =   ",;"   ;  
   
    vector<string>   v1   =   tokenize(src,   tok   ,true);  
    vector<string>   v2   =   tokenize(src,   tok   ,false,   "<null>");  
   
    cout<<"-------------v1:"<<endl;  
    for(int   i=0;   i<v1.size();i++)  
    {  
      cout<<v1[i].c_str()<<endl;  
    }  
     
    cout<<"-------------v2:"<<endl;  
    for(int   j=0;   j<v2.size();j++)  
    {  
      cout<<v2[j].c_str()<<endl;  
    }  
   
    try{  
     
      string   s   =   "######123#4###56########789###";  
      string   del   =   "";//"###";  
      vector<string>   v3   =   split(s,   del,   "<null>");  
      cout<<"-------------v3:"<<endl;  
      for(int   k=0;   k<v3.size();k++)  
      {  
        cout<<v3[k].c_str()<<endl;  
      }  
    }  
    catch   (char   *s)   {  
      cout<<s<<endl;  
    }  
   
    return   0;  
  }  
   
   
  2、CString版的:  
   
  #include   <stdio.h>  
  #include   <afx.h>  
   
  /*  
    *   该函数用delimits里的字符拆分s,传出一个CStringList指针pList,  
    *   若trim为真,则不保留分割后的空串(注意不是空白字符)。比如:  
    *   Tokenize(   "a,bc;,d,",   ",;",   &out_list,   TRUE)  
    *   会返回3个串:a、bc、d。  
    *   若trim为FALSE,则用nullSubst用来替代分割后的空串,比如:  
    *     Tokenize(   "a,bc;,d;",   ",;",   &out_list,   FALSE,"[null]"   )  
    *   会返回5个串:a、bc、[null]、d、[null]。  
    *   trim默认为FALSE,nullSubst默认为空串。  
    */  
  void   Tokenize(CString   s,   CString   delimits,   CStringList*   pList,   BOOL   trim=FALSE,   CString   nullSubst="")  
  {  
    ASSERT(   !s.IsEmpty()   &&   !delimits.IsEmpty()   );  
   
    s   +=   delimits[0];  
    for(   long   index=-1;   (index=s.FindOneOf((LPCTSTR)delimits))!=-1;   )  
    {  
      if(index   !=   0)   pList->AddTail(   s.Left(index)   );  
      else   if(!trim)   pList->AddTail(nullSubst);  
      s   =   s.Right(s.GetLength()-index-1);  
    }  
  }  
   
   
  /*    
    *   类似java字符串的split()方法。  
    *   使用一个完整的串delimit(而不是其中的某个字符)来分割src串,没有trim选项,  
    *   即严格分割。num用来确定最多分割为多少个串,如果是0(默认),则按照delimit  
    *   分割,若为1,则返回源串。  
    */  
  void   Split(const   CString&   src,   CString   delimit,   CStringList*   pOutList,   int   num=0,   CString   nullSubst="")  
  {  
    ASSERT(   !src.IsEmpty()   &&   !delimit.IsEmpty()   );  
    if(num==1)    
    {  
      pOutList->AddTail(src);  
      return;  
    }  
   
    int   deliLen   =   delimit.GetLength();  
    long   index   =   -1,   lastSearchPosition   =   0,   cnt   =   0;  
   
    while(   (index=src.Find(delimit,   lastSearchPosition))!=-1   )  
    {  
      if(index==lastSearchPosition)  
        pOutList->AddTail(nullSubst);  
      else  
        pOutList->AddTail(src.Mid(lastSearchPosition,   index-lastSearchPosition));  
      lastSearchPosition   =   index   +   deliLen;  
   
      if(num)  
      {  
        ++cnt;  
        if(cnt+1==num)   break;  
      }  
    }  
    CString   lastOne   =   src.Mid(lastSearchPosition);  
    pOutList->AddTail(   lastOne.IsEmpty()?   nullSubst:lastOne);  
  }  
   
   
   
  //   test  
  int   main(void)  
  {  
    CString   s   =   ",ab;cde,f,,;gh,,";  
    CString   sub   =   ",;";  
    CStringList   list1,list2;  
   
     
    Tokenize(s,sub,&list1,TRUE,"no   use");   //   <-----  
    printf("-------[Tokenize_trim]-------\n");  
    POSITION   pos1   =   list1.GetHeadPosition();  
    while(   pos1!=   NULL   )  
    {  
      printf(   list1.GetNext(pos1)   );  
      printf("\n");  
    }  
    Tokenize(s,sub,&list2,FALSE,"[null]");   //   <-----  
    printf("------[Tokenize_no_trim]-----\n");  
    POSITION   pos2   =   list2.GetHeadPosition();  
    while(   pos2!=   NULL   )  
    {  
      printf(   list2.GetNext(pos2)   );  
      printf("\n");  
    }  
     
    CStringList   list3;  
    s   =   "###0123###567######89###1000###";  
    sub   =   "###";  
    Split(s,sub,&list3,   3,   "<null>");   //   <-----  
    printf("------[Split]-----\n");  
    POSITION   pos3   =   list3.GetHeadPosition();  
    while(   pos3!=   NULL   )  
    {  
      printf(   list3.GetNext(pos3)   );  
      printf("\n");  
    }  
    return   0;    
  }  
  Top

3 楼collecte(问题虫)回复于 2006-03-08 17:26:04 得分 0

对   strtok这样一个隐患,标准库   和   MFC库   居然一直没有什么应对。   太奇怪了!Top

相关问题

  • 字符串分割。
  • 字符串分割
  • 分割字符串?
  • 字符串分割
  • 分割字符串
  • 分割字符串
  • 分割字符串
  • 字符串分割问题.
  • 怎样分割字符串?
  • 怎样分割字符串?

关键词

  • 字符
  • 函数
  • 指针
  • vector
  • delimit
  • lastsearchposition
  • nullsubst
  • 字符串
  • poutlist
  • 分割

得分解答快速导航

  • 帖主:collecte
  • cpio

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
惹火投票。。火热进行中...
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
CSDN网站24小时值班电话:13552009689
Copyright © 2000-2009, CSDN.NET, All Rights Reserved
GongshangLogo