`

标准C++ 与MFC 6.0 中字符串的分割

 
阅读更多

 

#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; 
}



转载自:http://www.cnblogs.com/qiangzi0303/archive/2007/09/28/908897.html

分享到:
评论

相关推荐

    VISUAL C++MFC扩展编程实例

    本书主要介绍了运用Visual C++ 5.0或6.0的高级编程技巧,内容涉及MFC程序设计的最新概念,全书提供了大量VC的编程实例,旨在帮助读者较为全面地掌握VC编程知识、技巧和方法。全书分为三个部分和附录。第一部分介绍...

    VC6.0_JSON串解析及生成_Dialog自测可用_jsoncpp-src-0.5.0

    程序开过过程简介: 1,网上下载jsoncpp-src-0.5.0 2,拷贝到自检工程下 3,jsoncpp-src-0.5.0\include\json下的所有文件添加到工程(add to project) ...C++通过jsoncpp类库读写JSON文件-json用法详解

    Visual C++ 6.0编程实例详解.part2

    1.1 MFC与C++ 1.2 VC++组件 1.3 安装 1.3.1 环境 1.3.2 安装过程 第2章 开发环境 2.1 主窗口 2.2 工具栏 2.2.1 Shaod工具栏 2.2.2 Build Mini-bar工具栏 2.3 菜单栏 2.3.1 File菜单 ...

    Visual C++应用教程-程序代码

    内容为:Visual C++6.0开发环境、基本C++语言、C++的面向对象程序设计、MFC基本应用程序的建立、对话框及常用控件、选单、工具栏和状态栏、框架窗口、文档和视图、绘图、数据库及媒体控制接口等。“实用教程”部分是...

    VC6.0实现POST和Get,调用后端WEBAPI接口_MFC版.rar

    //把字符串内容,写入Test.txt文件 OutFile.close(); //关闭Test.txt文件 //注意 这里返回的json数据 如果是中文的话,是 编码模式存在的,可以用jsoncppp解析,解析出来默认就是中文。 ::MessageBoxA(NULL,...

    Visual C++ 6.0编程实例详解.part1

    1.1 MFC与C++ 1.2 VC++组件 1.3 安装 1.3.1 环境 1.3.2 安装过程 第2章 开发环境 2.1 主窗口 2.2 工具栏 2.2.1 Shaod工具栏 2.2.2 Build Mini-bar工具栏 2.3 菜单栏 2.3.1 File菜单 ...

    VC++ 任意拆分字符串,用逗号隔开

    VC/C++源码,字符处理,字符串 VC++ 以逗号为分隔点,自由任意拆分字符串,经常编写代码的朋友可能会想到Split,对,本代码就是使用Split函数实现分隔字符串,这相当实用,在日常编程中,对字符串的截娶过滤与分隔是...

    Visual C++ MFC扩展编程实例.PDF

    本书主要介绍了运用Visual C++ 5.0或6.0的高级编程技巧,内容涉及MFC程序设计的最新概念,全书提供了大量VC的编程实例,旨在帮助读者较为全面地掌握VC编程知识、技巧和方法。全书分为三个部分和附录。第一部分介绍...

    标准MFC WinSock ActiveX控件开发实例

    case VT_BSTR://字符串型 IPAddress = CString(RemoteHost.bstrVal); break; case VT_BYREF|VT_I1://CHAR * IPAddress.Format("%s",RemoteHost.pcVal);//RemoteHost.pbstrVal); break; default: ...

    C++mfc写的与arduino串口通讯控制机械臂.zip

    vc++6.0写的一个串口控制6舵机机械臂的上位机软件,可进行二次修改重新定制界面以及所发送的字符串. 生成的exe不受串口控件限制,因为我采用的是一位大佬写的的一个串口类,理论上可在任意Windows平台上运行,希望能帮到...

    Microsoft visual c++ 6.0 programmer's Guide 程序员指南

    字符串资源和状态栏 位图. 工具栏. 图标和光标 向DiskPie1添加代码 再谈未结合命令 修整资源数据 第5章 对话框和控件 对话脚本 对话编辑器 例1:修改 About对话 例2:简单的非模态对话框 例3:向AppWizard程序添加...

    VC在编辑框中实现多行显示

    VC在编辑框中实现固定格式的多行显示,是一些基础知识的典型应用,VC入门者可参考哦。

    C++语言程序设计习题与实验指导

    第六章:数组、指针与字符串 第七章:继承与派生 第八章:多态性 第九章:群体类 第十章:群体数据的组织 第十一章:流类库与输入/输出 第十二章:异常处理 第十三章:MFC库与Windows程序开发概述 第二部分...

    可计算字符串值的动态联接库

    可以计算最多由20个参数值double*及对应字符串char*组成的计算式,可以返回计算结果,计算式字符串中可以包含+ - * /^ ()以及SIN,COS等20多个函数,如果你的程序中需要大量的计算问题,你十分不耐烦编写一条又一条...

    vc连接oracle数据库

    最初的代码,也是我从csdn下载的,最初的代码是c风格,我引入了三个经典的Ado类,增加...连接字符串是从tns配置文件里,直接拷过来的,连接字符串写不对,就连接不上,最好自动生成或从配置文件里直接拷。 连接oracle

    VC自动登录telnet发送命令(改进版)

    自己写的vc程序自动登录telnet并发送命令的函数,十分简单。新手,写的不好,不过希望能对大家有所帮助

    mfc 多功能 计算器

    核心功能是对字符串进行解析,分析出算式。能进行+-*/四则运算,还能进行成方,sin,cos,tan,ln,sqrt计算。界面为一个简单对话框。适合初学者研究算法,开发思路。有问题可以发邮件到jianger2005@sina.com,也...

    VisualC++程序设计教程例10_1(MFC下创建带菜单的程序)

    创建一个包含有“代码操作”菜单的应用程序,在“代码操作”菜单中包含有“显示ASCII”,“显示256色”等功能,其中选择“显示ASCII”选项时,在编辑框中显示0——255的ASCII字符,当选择“显示256色”时,在窗口中...

    基于C_S结构的Socket程序设计(含源码MFC和WIN32)

    本程序中当client使用TCP socket连接TCP Server成功后,client端要向TCP Server发送“GET UDP PORT”命令字符串,Server收到后再向client回送自己的UDP Server 端口号(题目要求TCP Server建立连接后直接将UDP端口号...

Global site tag (gtag.js) - Google Analytics