看流星社区

 找回密码
 注册账号
查看: 2202|回复: 0

在VC中处理符号分隔的字符串

[复制链接]

该用户从未签到

发表于 2013-2-9 09:26:59 | 显示全部楼层 |阅读模式
一。前言
程序中经常会遇到要处理用某些符号(如空格,或“, ; . | \t”等)分隔的字符串的问题,我在此做了一些总结和比较。

二。处理方法
1. 用MFC CString之Find处理字符串
// 以下方法将一个字符串分解后放到一个CStringArray中:
  1. void ExtractString(CStringArray& arr, const CString strSrc, const CString sep = "\r\n" )
  2. {
  3. // 预处理: 可根据需要决定是否需要Trim,以及是Trim掉空格/还是分隔符/还是其它
  4. CString str(strSrc);
  5. str.TrimLeft();
  6. str.TrimRight();
  7. if(str.IsEmpty())
  8.    return;
  9. // 开始分解
  10. int pos = str.Find(sep);
  11. while (pos != -1)
  12. {
  13.    //if(!str.Left(pos).IsEmpty()) // 如有必要也可在此Trim后再判断是否为空,为空则舍弃
  14.    arr.Add(str.Left(pos));
  15.    str = str.Mid(pos + sep.GetLength());
  16.    pos = str.Find(sep);
  17. }
  18. arr.Add(str); // think
  19. }
复制代码
// BTW,CString提供了TrimLeft和TrimRight,却不能一次TrimAll,并返回Trim后的字符串:
  1. CString TrimAll(CString& str, CString strTrim = " ")
  2. {
  3. str.TrimLeft(strTrim);
  4. str.TrimRight(strTrim);
  5. return CString(str);
  6. }
复制代码
// 同样是用Find处理字符串,和以上处理方式稍有不同,试比较:
  1. void ExtractString2(CStringArray& arr, const CString strSrc, const CString sep = "\r\n" )
  2. {
  3.    CString str(strSrc);
  4.    if(TrimAll(str).IsEmpty())
  5.    return;
  6. // 开始分解
  7. int pos = str.Find(sep);
  8. if(pos == -1) // 未找到分隔符
  9.    arr.Add(str);
  10. else    // 找到分隔符
  11. {
  12.    str += sep;     // think
  13.    CString s;
  14.    while (pos != -1)
  15.    {
  16.     s = str.Left(pos);
  17.     if(!TrimAll(s).IsEmpty())
  18.      arr.Add(s);
  19.     str = str.Mid(pos + sep.GetLength());
  20.     pos = str.Find(sep);
  21.    }
  22. }
  23. }
复制代码
2. 用MFC未公开函数AfxExtractSubString 处理
  1. // 以下为函数定义及说明:
  2. // AfxExtractSubString 从一个字符(chSep)分隔的字符串(lpszFullString)中取出第iSubString个子串,输出到rString
  3. BOOL AFXAPI AfxExtractSubString (   
  4.      CString& rString,                  // 用于输出子串
  5.      LPCTSTR lpszFullString,      // 被分隔的字符串
  6.      int iSubString,                       // zero-based substring index
  7.      TCHAR chSep = '\n'            // 分隔符
  8.      )
  9. // eg:
  10. CString sDesc= "张三|男|28|医生";
  11. CString sOccupation;
  12. if(AfxExtractSubString ( sOccupation, sDesc, 3, '|'))
  13.      cout << "职业:" << sOccupation << endl;
复制代码
3. 用C语言之strtok函数处理
  1. #include <assert.h>
  2. void test()
  3. {
  4. char* str = "06317377244|13805871280|20040210105049|193|NBGW1|040C|0017|8";
  5. char seps[]    = ",;|";
  6. char* temp = (char*)malloc(sizeof(char) * (strlen(str)+1));
  7.      strcpy(temp, str);
  8.      char* token = strtok(temp, seps);
  9.      while (NULL != token)
  10.      {
  11.    printf("%s\t", token);
  12.    token = strtok(NULL, seps);
  13.      }
  14. free(temp);
  15. }
复制代码
4. 其它方法
当然既然能用MFC的Find函数进行处理,也可能string的find处理,甚至可用最原始的字符比较,再配合一些字串处理函数进行处理。以下再介绍一种用sscanf配合通配符方法:
  1. CString str = "abc$中国$12345$,。‘ ";
  2. char a1[8],a2[8],a3[8],a4[8];
  3. sscanf(str,"%[^$]$%[^$]$%[^$]$%[^&]",a1,a2,a3,a4);
  4. AfxMessageBox(str);
  5. AfxMessageBox(a1);
  6. AfxMessageBox(a2);
  7. AfxMessageBox(a3);
  8. AfxMessageBox(a4);
复制代码
但我觉得我提供的使用Find类函数处理字串的2种方法非常常用,可供参考。

三。比较
处理方法                                                                 
用MFC CString之Find处理字符串
优:   分隔符可是是字符或字串;在MFC中是最常用的方法。
劣:   仅限于MFC中使用

用AfxExtractSubString 处理
优:   完全封装,调用简单;分隔符可是是字符或字串。
劣:   仅限于MFC中使用,且未公开;一般用于取其中某个子串。
  
用C语言之strtok函数处理
优:   分隔符可以同时指定多个字符,可用于分隔符不是很确定的情况。
劣: 分隔符只能是字符;C库函数,在C兼容开发环境中通用。


四。后记
以上只是我从个人的角度做的一个小结(我用MFC/C++多一些),难免有失偏颇,在BCB/Delphi中肯定也有对应的方式方法,不在本文的讨论范围内,这里就不再赘述。
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-5-4 00:59

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表