- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
一。前言
程序中经常会遇到要处理用某些符号(如空格,或“, ; . | \t”等)分隔的字符串的问题,我在此做了一些总结和比较。
二。处理方法
1. 用MFC CString之Find处理字符串
// 以下方法将一个字符串分解后放到一个CStringArray中:- void ExtractString(CStringArray& arr, const CString strSrc, const CString sep = "\r\n" )
- {
- // 预处理: 可根据需要决定是否需要Trim,以及是Trim掉空格/还是分隔符/还是其它
- CString str(strSrc);
- str.TrimLeft();
- str.TrimRight();
- if(str.IsEmpty())
- return;
- // 开始分解
- int pos = str.Find(sep);
- while (pos != -1)
- {
- //if(!str.Left(pos).IsEmpty()) // 如有必要也可在此Trim后再判断是否为空,为空则舍弃
- arr.Add(str.Left(pos));
- str = str.Mid(pos + sep.GetLength());
- pos = str.Find(sep);
- }
- arr.Add(str); // think
- }
复制代码 // BTW,CString提供了TrimLeft和TrimRight,却不能一次TrimAll,并返回Trim后的字符串:- CString TrimAll(CString& str, CString strTrim = " ")
- {
- str.TrimLeft(strTrim);
- str.TrimRight(strTrim);
- return CString(str);
- }
复制代码 // 同样是用Find处理字符串,和以上处理方式稍有不同,试比较:- void ExtractString2(CStringArray& arr, const CString strSrc, const CString sep = "\r\n" )
- {
- CString str(strSrc);
- if(TrimAll(str).IsEmpty())
- return;
- // 开始分解
- int pos = str.Find(sep);
- if(pos == -1) // 未找到分隔符
- arr.Add(str);
- else // 找到分隔符
- {
- str += sep; // think
- CString s;
- while (pos != -1)
- {
- s = str.Left(pos);
- if(!TrimAll(s).IsEmpty())
- arr.Add(s);
- str = str.Mid(pos + sep.GetLength());
- pos = str.Find(sep);
- }
- }
- }
复制代码 2. 用MFC未公开函数AfxExtractSubString 处理- // 以下为函数定义及说明:
- // AfxExtractSubString 从一个字符(chSep)分隔的字符串(lpszFullString)中取出第iSubString个子串,输出到rString
- BOOL AFXAPI AfxExtractSubString (
- CString& rString, // 用于输出子串
- LPCTSTR lpszFullString, // 被分隔的字符串
- int iSubString, // zero-based substring index
- TCHAR chSep = '\n' // 分隔符
- )
- // eg:
- CString sDesc= "张三|男|28|医生";
- CString sOccupation;
- if(AfxExtractSubString ( sOccupation, sDesc, 3, '|'))
- cout << "职业:" << sOccupation << endl;
复制代码 3. 用C语言之strtok函数处理- #include <assert.h>
- void test()
- {
- char* str = "06317377244|13805871280|20040210105049|193|NBGW1|040C|0017|8";
- char seps[] = ",;|";
- char* temp = (char*)malloc(sizeof(char) * (strlen(str)+1));
- strcpy(temp, str);
- char* token = strtok(temp, seps);
- while (NULL != token)
- {
- printf("%s\t", token);
- token = strtok(NULL, seps);
- }
- free(temp);
- }
复制代码 4. 其它方法
当然既然能用MFC的Find函数进行处理,也可能string的find处理,甚至可用最原始的字符比较,再配合一些字串处理函数进行处理。以下再介绍一种用sscanf配合通配符方法:- CString str = "abc$中国$12345$,。‘ ";
- char a1[8],a2[8],a3[8],a4[8];
- sscanf(str,"%[^$]$%[^$]$%[^$]$%[^&]",a1,a2,a3,a4);
- AfxMessageBox(str);
- AfxMessageBox(a1);
- AfxMessageBox(a2);
- AfxMessageBox(a3);
- AfxMessageBox(a4);
复制代码 但我觉得我提供的使用Find类函数处理字串的2种方法非常常用,可供参考。
三。比较
处理方法
用MFC CString之Find处理字符串
优: 分隔符可是是字符或字串;在MFC中是最常用的方法。
劣: 仅限于MFC中使用
用AfxExtractSubString 处理
优: 完全封装,调用简单;分隔符可是是字符或字串。
劣: 仅限于MFC中使用,且未公开;一般用于取其中某个子串。
用C语言之strtok函数处理
优: 分隔符可以同时指定多个字符,可用于分隔符不是很确定的情况。
劣: 分隔符只能是字符;C库函数,在C兼容开发环境中通用。
四。后记
以上只是我从个人的角度做的一个小结(我用MFC/C++多一些),难免有失偏颇,在BCB/Delphi中肯定也有对应的方式方法,不在本文的讨论范围内,这里就不再赘述。 |
|