关于字符串分割!!求助 现在有一段中文 想要按照标点分隔成 一个一个的CString?不知道有没有这函数? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 Vc里没有,c#里有,自己写个int SplitString(CString string,CStringArray& array,char split){ CString strTemp=string; array.RemoveAll(); int nPos=strTemp.Find(split); while (nPos>-1) { array.Add(strTemp.Left(nPos)); strTemp=strTemp.Mid(nPos+1); nPos=strTemp.Find(split); } array.Add(strTemp); return array.GetSize();} 用 _tcstok_s 或 CStringT::Tokenize 自己分INT_PTR TokenizeStr(LPCTSTR lpSrc, LPCTSTR pszTokens, CStringArray &szArray){ CString szSrc(lpSrc), resToken; int curPos = 0; while((resToken = szSrc.Tokenize(pszTokens, curPos)) && (!resToken.IsEmpty())) { szArray.Add(resToken); TRACE(_T("%s\n"), resToken); } return szArray.GetSize();}//测试代码 CStringArray szArray; TokenizeStr(_T("%First Second#Third"), _T("%# "), szArray);//输出FirstSecondThird 有一个win32 api 专门干这项工作! AfxExtractSubString... 第一种:AfxExtractSubString,该函数在MSDN文档中没有说明,但在分割字符串时很有用,当然也可用Find自己去写。函数原型:BOOL AfxExtractSubString(CString& rString, LPCTSTR lpszFullString, int iSubString, TCHAR chSep = '\n')参数说明:rString 保存输出的子字符串lpszFullString 待分割的字符串iSubString 提取的子字符串的序号,从0开始。假如你想提取第3段,该参数就输入2chSep 用于分割的字符,默认的是'\n' 返回值:分割成功,就返回TRUE;iSubString越界,则返回FALSE举例说明:CString str = _T("abc45,78ea,679u,368");CString strSub;AfxExtractSubString(strSub, (LPCTSTR)str, 0, ','); // strSub的内容为abc45AfxExtractSubString(strSub, (LPCTSTR)str, 3, ','); // strSub的内容为368注意:用于分割的只能是字符,不能是字符串。第二种一._tcstok函数 在MFC中,一个CString str="ab ac dd PM",怎么把他分开成ab和ac和dd和PM这四个字符串,类似string的split的功能? _tcstok声明头文件: char* _tcstok( char* strToken, const char* strDelimit ); 该函数是可以从一个CString串中,根据提供的分隔符,截取并返回一个一个的Token; 参数: strToken: 是一个要分析的串;这个串中包含一个或者多个Token,当然还有分隔符,也有可 能有其他的字符; strDelimit: 是分隔符;根据分隔符把strToken中的Token分析出来; //==============test1:_tcstok=============== //将以空格符为分隔符对str进行分割 CString str = _T("192.168.89.125"); TCHAR seps[] = _T("."); TCHAR* token = _tcstok( (LPTSTR)(LPCTSTR)str, seps ); while( token != NULL ) { printf("str=%s token=%s\n",str,token); token = _tcstok( NULL, seps ); } //==============test1:end================== 执行结果如下: str=192 token=192 str=192 token=168 str=192 token=89 str=192 token=125 第一次调用的时候,函数会忽略出现在strToken串开始的分隔符,返回找到的Token指针,用空字符(NULL character )替换掉已经查找到的部分(包括分隔符)并把"新"串保存到一个Static变量中(系统来完成); 如果下次调用时第一个参数为NULL的话,函数从Static变量中取出串,根据分隔符得到并返回新Token,用空字符(NULL character )替换掉已经查找到的部分(包括分隔符)并重新保存"新"串;如此循环,直到循环条件结束。 参考:http://biao3730.spaces.live.com/Blog/cns!3415F543A 07A7AE5!175.entry 也可以使用char * __cdecl strtok(char *, const char *);(包含在头文件中) 参考:http://baike.baidu.com/view/1028553.htm 或者自己写个分割函数实现split的功能, 第三种: 一个这样的字符串:“123,456,789,0”。把他截取成这样的字符串数组 [123],[456],[789],[0]。#include <iostream>#include <string>#include <vector>using namespace std;vector<string> splitEx(const string& src, string separate_character){ vector<string> strs; int separate_characterLen = separate_character.size();//分割字符串的长度,这样就可以支持如“,,”多字符串的分隔符 int lastPosition = 0,index = -1; while (-1 != (index = src.find(separate_character,lastPosition))) { strs.push_back(src.substr(lastPosition,index - lastPosition)); lastPosition = index + separate_characterLen; } string lastString = src.substr(lastPosition);//截取最后一个分隔符后的内容 if (!lastString.empty()) strs.push_back(lastString);//如果最后一个分隔符后还有内容就入队 return strs;}int _tmain(int argc, _TCHAR* argv[]){ string s = "123,456,789,0,888"; string del = ","; vector<string> strs = splitEx(s, del); for ( unsigned int i = 0; i < strs.size(); i++) { cout << strs[i].c_str() << endl; } return 0; }或者:void Split(CString source, CStringArray& dest, CString division)...{ dest.RemoveAll(); int pos = 0; int pre_pos = 0; while( -1 != pos )...{ pre_pos = pos; pos = source.Find(division,(pos+1)); dest.Add(source.Mid(pre_pos,(pos-pre_pos))); }}CString source是须要截取的原字符串,CStringArray& dest 是终极成果的数组CString division 是用来做分别符的字符串第四种:MFC下Split功能四个参数说明如下:a:要分割的字符串b:存放的数组,要定义到足够能放下所有分割结果。c:分割后实际生成的数组元素最大下标,如果没有元素生成,则函数调用后为-1。注意,c在函数调用后值要发生变化,这是一个地址引用参数。d:分隔符,长度不限,并不限定为一个字符void Split(CString a, CString *b, int &c, CString d){int d_len=d.GetLength();int j=0;int n=0;int m_pos;while(1){ m_pos= a.Find(d,j); if(m_pos==-1 && j==0) { c=-1; break; } if(m_pos==-1 && j!=0) { b[n]=a.Mid(j,a.GetLength()-j); c=n; break; } if(j==0) { b[n]=a.Mid(0,m_pos); j=m_pos+d_len; } else { b[n]=a.Mid(j,m_pos-j); j=m_pos+d_len; } n++;}}下面举例说明调用方法:CString b[20];CString a="hello0|!nihao|!how are you|!123456|!111";int c=0;CString d="!";CString t; Split(a,b,c,d);if (c!=-1){for (int i=0;i<=c;i++){AfxMessageBox(b[i]);}}else{AfxMessageBox("找不到此项");} 在复杂了就用正则表达式吧,vc6.0本身不带正则类,有一个greta正则表达式类,是微软研究院开发的,可以从网上下载,支持vc6.0.vc.net自身支持正则System::Text::RegularExpressions 是包含正则表达式支持功能的命名空间http://www.bianceng.cn/Programming/VC_NET/200912/13318_2.htmusing namespace System::Text::RegularExpressions;void doTheMatch( String^ inputString, String^ filter ){Console::WriteLine( "original string: {0}", inputString );Console::WriteLine( "attempt to match: {0}", filter );Regex^ regex = gcnew Regex( filter );Match^ match = regex->Match( inputString );if ( ! match->Success ){Console::WriteLine("Sorry, no match of {0} in {1}", filter, inputString );return;}for ( ; match->Success; match = match->NextMatch() ){Console.WriteLine("The characters {0} match beginning at position {1}",match->ToString(), match->Index );}}Regex 类表示正则表达式。您传递的是它的构造函数,即表达式的字符串表示形式。Regex 对象构造完成之后,与之关联的正则表达式便固定不变。也就是说,您不能更改它。因而您的程序中的每个正则表达式均需要自己的 Regex 对象。Match 方法负责对其字符串参数执行实际的正则表达式匹配算法。它返回一个 Match 类对象,该对象带有模式匹配的结果。Match 对象也是固定不变的。要查看匹配是否成功,请查询 Match 类的 Success 属性。每个匹配称为一个捕捉。Index 属性返回在原始字符串中找到的被捕获子串的第一个字符所在的位置。Length 返回被捕获子串的长度。ToString 方法返回被捕获子串。Regex 类的 Split 方法十分有用。与 String 类的 Split 方法的相似之处是:它返回一个字符串数组。与 String 的方法不相似的地方是,它根据正则表达式(而不是根据一组字符)来拆分输入字符串: 好吧,我比较喜欢偷懒,我把标点替换成比较特殊的符号了,然后find位置再截取,放进数组里,虽然没用你给的方法,还是谢谢你,分都给你了谢谢! 出现0x0000002c内存不能为"read"的问题 求一方法封装字符串 关于自绘Button的问题,请教大家,欢迎讨论 如何融合多个project成为一个solution? 欢迎高人讨论赐教:WSASend的lpBuffers有可能因为底层的发送缓冲不足而被锁定,那么很多的Overlap I/O锁定同一块内存,不会出其他问题吧 如何安全的删除控件? 画图的问题 (急)如何用代码设置Video Sourse,不用调出属性页? 这问题如何解决? 请问如何用一个程序向另外一个程序发送消息使得该程序中的按扭可用? 新手上路Win32 MFC CXImage编译出的DLL太大,怎样缩小体积。
int SplitString(CString string,CStringArray& array,char split)
{
CString strTemp=string;
array.RemoveAll();
int nPos=strTemp.Find(split);
while (nPos>-1)
{
array.Add(strTemp.Left(nPos));
strTemp=strTemp.Mid(nPos+1);
nPos=strTemp.Find(split);
}
array.Add(strTemp);
return array.GetSize();
}
INT_PTR TokenizeStr(LPCTSTR lpSrc, LPCTSTR pszTokens, CStringArray &szArray)
{
CString szSrc(lpSrc), resToken;
int curPos = 0;
while((resToken = szSrc.Tokenize(pszTokens, curPos))
&& (!resToken.IsEmpty()))
{
szArray.Add(resToken);
TRACE(_T("%s\n"), resToken);
}
return szArray.GetSize();
}//测试代码
CStringArray szArray;
TokenizeStr(_T("%First Second#Third"), _T("%# "), szArray);
//输出
First
Second
Third
AfxExtractSubString,该函数在MSDN文档中没有说明,但在分割字符串时很有用,当然也可用Find自己去写。函数原型:BOOL AfxExtractSubString(CString& rString, LPCTSTR lpszFullString, int iSubString, TCHAR chSep = '\n')参数说明:rString 保存输出的子字符串lpszFullString 待分割的字符串iSubString 提取的子字符串的序号,从0开始。假如你想提取第3段,该参数就输入2chSep 用于分割的字符,默认的是'\n' 返回值:分割成功,就返回TRUE;iSubString越界,则返回FALSE举例说明:CString str = _T("abc45,78ea,679u,368");CString strSub;AfxExtractSubString(strSub, (LPCTSTR)str, 0, ','); // strSub的内容为abc45AfxExtractSubString(strSub, (LPCTSTR)str, 3, ','); // strSub的内容为368注意:用于分割的只能是字符,不能是字符串。第二种
一._tcstok函数
在MFC中,一个CString str="ab ac dd PM",怎么把他分开成ab和ac和dd和PM这四个字符串,类似string的split的功能?
_tcstok声明头文件:
char* _tcstok( char* strToken, const char* strDelimit );
该函数是可以从一个CString串中,根据提供的分隔符,截取并返回一个一个的Token;
参数:
strToken: 是一个要分析的串;这个串中包含一个或者多个Token,当然还有分隔符,也有可
能有其他的字符;
strDelimit: 是分隔符;根据分隔符把strToken中的Token分析出来;
//==============test1:_tcstok===============
//将以空格符为分隔符对str进行分割
CString str = _T("192.168.89.125");
TCHAR seps[] = _T(".");
TCHAR* token = _tcstok( (LPTSTR)(LPCTSTR)str, seps );
while( token != NULL )
{
printf("str=%s token=%s\n",str,token);
token = _tcstok( NULL, seps );
}
//==============test1:end==================
执行结果如下:
str=192 token=192
str=192 token=168
str=192 token=89
str=192 token=125
第一次调用的时候,函数会忽略出现在strToken串开始的分隔符,返回找到的Token指针,用空字符(NULL character )替换掉已经查找到的部分(包括分隔符)并把"新"串保存到一个Static变量中(系统来完成);
如果下次调用时第一个参数为NULL的话,函数从Static变量中取出串,根据分隔符得到并返回新Token,用空字符(NULL character )替换掉已经查找到的部分(包括分隔符)并重新保存"新"串;如此循环,直到循环条件结束。
参考:http://biao3730.spaces.live.com/Blog/cns!3415F543A 07A7AE5!175.entry
也可以使用char * __cdecl strtok(char *, const char *);(包含在头文件中)
参考:http://baike.baidu.com/view/1028553.htm 或者自己写个分割函数实现split的功能,
第三种:
一个这样的字符串:“123,456,789,0”。把他截取成这样的字符串数组 [123],[456],[789],[0]。#include <iostream>
#include <string>
#include <vector>
using namespace std;vector<string> splitEx(const string& src, string separate_character)
{
vector<string> strs;
int separate_characterLen = separate_character.size();//分割字符串的长度,这样就可以支持如“,,”多字符串的分隔符
int lastPosition = 0,index = -1;
while (-1 != (index = src.find(separate_character,lastPosition)))
{
strs.push_back(src.substr(lastPosition,index - lastPosition));
lastPosition = index + separate_characterLen;
}
string lastString = src.substr(lastPosition);//截取最后一个分隔符后的内容
if (!lastString.empty())
strs.push_back(lastString);//如果最后一个分隔符后还有内容就入队
return strs;
}int _tmain(int argc, _TCHAR* argv[])
{
string s = "123,456,789,0,888";
string del = ",";
vector<string> strs = splitEx(s, del);
for ( unsigned int i = 0; i < strs.size(); i++)
{
cout << strs[i].c_str() << endl;
}
return 0;
}
或者:
void Split(CString source, CStringArray& dest, CString division)
...{
dest.RemoveAll();
int pos = 0;
int pre_pos = 0;
while( -1 != pos )...{
pre_pos = pos;
pos = source.Find(division,(pos+1));
dest.Add(source.Mid(pre_pos,(pos-pre_pos)));
}}
CString source是须要截取的原字符串,CStringArray& dest 是终极成果的数组CString division 是用来做分别符的字符串第四种:
MFC下Split功能
四个参数说明如下:
a:要分割的字符串
b:存放的数组,要定义到足够能放下所有分割结果。
c:分割后实际生成的数组元素最大下标,如果没有元素生成,则函数调用后为-1。注意,c在函数调用后值要发生变化,这是一个地址引用参数。
d:分隔符,长度不限,并不限定为一个字符
void Split(CString a, CString *b, int &c, CString d)
{
int d_len=d.GetLength();
int j=0;
int n=0;
int m_pos;
while(1)
{
m_pos= a.Find(d,j);
if(m_pos==-1 && j==0)
{
c=-1;
break;
}
if(m_pos==-1 && j!=0)
{
b[n]=a.Mid(j,a.GetLength()-j);
c=n;
break;
}
if(j==0)
{
b[n]=a.Mid(0,m_pos);
j=m_pos+d_len;
}
else
{
b[n]=a.Mid(j,m_pos-j);
j=m_pos+d_len;
}
n++;
}
}
下面举例说明调用方法:
CString b[20];
CString a="hello0|!nihao|!how are you|!123456|!111";
int c=0;
CString d="!";
CString t;
Split(a,b,c,d);
if (c!=-1)
{
for (int i=0;i<=c;i++)
{
AfxMessageBox(b[i]);
}
}
else
{
AfxMessageBox("找不到此项");
}
vc.net自身支持正则
System::Text::RegularExpressions 是包含正则表达式支持功能的命名空间
http://www.bianceng.cn/Programming/VC_NET/200912/13318_2.htmusing namespace System::Text::RegularExpressions;
void doTheMatch( String^ inputString, String^ filter )
{
Console::WriteLine( "original string: {0}", inputString );
Console::WriteLine( "attempt to match: {0}", filter );
Regex^ regex = gcnew Regex( filter );
Match^ match = regex->Match( inputString );
if ( ! match->Success )
{
Console::WriteLine(
"Sorry, no match of {0} in {1}", filter, inputString );
return;
}
for ( ; match->Success; match = match->NextMatch() )
{
Console.WriteLine(
"The characters {0} match beginning at position {1}",
match->ToString(), match->Index );
}
}
Regex 类表示正则表达式。您传递的是它的构造函数,即表达式的字符串表示形式。Regex 对象构造完成之后,与之关联的正则表达式便固定不变。也就是说,您不能更改它。因而您的程序中的每个正则表达式均需要自己的 Regex 对象。
Match 方法负责对其字符串参数执行实际的正则表达式匹配算法。它返回一个 Match 类对象,该对象带有模式匹配的结果。Match 对象也是固定不变的。
要查看匹配是否成功,请查询 Match 类的 Success 属性。每个匹配称为一个捕捉。Index 属性返回在原始字符串中找到的被捕获子串的第一个字符所在的位置。Length 返回被捕获子串的长度。ToString 方法返回被捕获子串。
Regex 类的 Split 方法十分有用。与 String 类的 Split 方法的相似之处是:它返回一个字符串数组。与 String 的方法不相似的地方是,它根据正则表达式(而不是根据一组字符)来拆分输入字符串: