CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
IBM Rational 系统开发最佳实践工具包 WebSphere MQ 最佳实践 TOP 15
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 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo