开发工具-拆分有分隔符的字符串操作类

128 阅读3分钟

CCmdStr类用于拆分有分隔符的字符串。

字符串的格式为:字段内容1+分隔符+字段内容2+分隔符+字段内容3+分隔符+...+字段内容n。
例如:"messi,10,striker,30,1.72,68.5,Barcelona",这是足球运动员梅西的资料,
包括姓名、球衣号码、场上位置、年龄、身高、体重和效力的俱乐部,字段之间用半角的逗号分隔。
class CCmdStr
{
public:
  vector<string> m_vCmdStr;  // 存放拆分后的字段内容。

  CCmdStr();  // 构造函数。
  CCmdStr(const string &buffer,const char *sepstr,const bool bdelspace=false);

  // 把字符串拆分到m_vCmdStr容器中。
  // buffer:待拆分的字符串。
  // sepstr:buffer中采用的分隔符,注意,sepstr参数的数据类型不是字符,是字符串,如","、" "、"|"、"~!~"。
  // bdelspace:拆分后是否删除字段内容前后的空格,true-删除;false-不删除,缺省不删除。
  void SplitToCmd(const string &buffer,const char *sepstr,const bool bdelspace=false);

  // 获取拆分后字段的个数,即m_vCmdStr容器的大小。
  int CmdCount();

  // 从m_vCmdStr容器获取字段内容。
  // inum:字段的顺序号,类似数组的下标,从0开始。
  // value:传入变量的地址,用于存放字段内容。
  // 返回值:true-成功;如果inum的取值超出了m_vCmdStr容器的大小,返回失败。
  bool GetValue(const int inum,char *value,const int ilen=0); // 字符串,ilen缺省值为0。
  bool GetValue(const int inum,int  *value); // int整数。
  bool GetValue(const int inum,unsigned int *value); // unsigned int整数。
  bool GetValue(const int inum,long *value); // long整数。
  bool GetValue(const int inum,unsigned long *value); // unsigned long整数。
  bool GetValue(const int inum,double *value); // 双精度double。
  bool GetValue(const int inum,bool *value); // bool型。

  ~CCmdStr(); // 析构函数。
};

----cpp
CCmdStr::CCmdStr()
{
  m_vCmdStr.clear();
}

CCmdStr::CCmdStr(const string &buffer,const char *sepstr,const bool bdelspace)
{
  m_vCmdStr.clear();
  SplitToCmd(buffer,sepstr,bdelspace);
}

// 把字符串拆分到m_vCmdStr容器中。
// buffer:待拆分的字符串。
// sepstr:buffer字符串中字段内容的分隔符,注意,分隔符是字符串,如","、" "、"|"、"~!~"。
// bdelspace:是否删除拆分后的字段内容前后的空格,true-删除;false-不删除,缺省不删除。
void CCmdStr::SplitToCmd(const string &buffer,const char *sepstr,const bool bdelspace)
{
  // 清除所有的旧数据
  m_vCmdStr.clear();
  int iPOS=0;
  string srcstr,substr;
  srcstr=buffer;
  while ( (iPOS=srcstr.find(sepstr)) >= 0)
  {
    substr=srcstr.substr(0,iPOS);
    if (bdelspace == true)
    {
      char str[substr.length()+1];
      STRCPY(str,sizeof(str),substr.c_str());
      DeleteLRChar(str,' ');
      substr=str;
    }
    m_vCmdStr.push_back(substr);
    iPOS=iPOS+strlen(sepstr);
    srcstr=srcstr.substr(iPOS,srcstr.size()-iPOS);
  }

  substr=srcstr;

  if (bdelspace == true)
  {
    char str[substr.length()+1];
    STRCPY(str,sizeof(str),substr.c_str());
    DeleteLRChar(str,' ');
    substr=str;
  }

  m_vCmdStr.push_back(substr);

  return;
}

int CCmdStr::CmdCount()
{
  return m_vCmdStr.size();
}

bool CCmdStr::GetValue(const int inum,char *value,const int ilen)
{
  if ( (inum>=(int)m_vCmdStr.size()) || (value==0) ) return false;
  if (ilen>0) memset(value,0,ilen+1);   // 调用者必须保证value的空间足够,否则这里会内存溢出。
  if ( (m_vCmdStr[inum].length()<=(unsigned int)ilen) || (ilen==0) )
  {
    strcpy(value,m_vCmdStr[inum].c_str());
  }
  else
  {
    strncpy(value,m_vCmdStr[inum].c_str(),ilen); value[ilen]=0;
  }
  return true;
}

bool CCmdStr::GetValue(const int inum,int *value)
{
  if ( (inum>=(int)m_vCmdStr.size()) || (value==0) ) return false;

  (*value) = 0;

  if (inum >= (int)m_vCmdStr.size()) return false;

  (*value) = atoi(m_vCmdStr[inum].c_str());

  return true;
}

bool CCmdStr::GetValue(const int inum,unsigned int *value)
{
  if ( (inum>=(int)m_vCmdStr.size()) || (value==0) ) return false;
  (*value) = 0;
  if (inum >= (int)m_vCmdStr.size()) return false;
  (*value) = atoi(m_vCmdStr[inum].c_str());
  return true;
}


bool CCmdStr::GetValue(const int inum,long *value)
{
  if ( (inum>=(int)m_vCmdStr.size()) || (value==0) ) return false;
  (*value) = 0;
  if (inum >= (int)m_vCmdStr.size()) return false;
  (*value) = atol(m_vCmdStr[inum].c_str());
  return true;
}

bool CCmdStr::GetValue(const int inum,unsigned long *value)
{
  if ( (inum>=(int)m_vCmdStr.size()) || (value==0) ) return false;
  (*value) = 0;
  if (inum >= (int)m_vCmdStr.size()) return false;
  (*value) = atol(m_vCmdStr[inum].c_str());
  return true;
}

bool CCmdStr::GetValue(const int inum,double *value)
{
  if ( (inum>=(int)m_vCmdStr.size()) || (value==0) ) return false;
  (*value) = 0;
  if (inum >= (int)m_vCmdStr.size()) return false;
  (*value) = (double)atof(m_vCmdStr[inum].c_str());
  return true;
}

bool CCmdStr::GetValue(const int inum,bool *value)
{
  if ( (inum>=(int)m_vCmdStr.size()) || (value==0) ) return false;
  (*value) = 0;
  if (inum >= (int)m_vCmdStr.size()) return false;
  char strTemp[11];
  memset(strTemp,0,sizeof(strTemp));
  strncpy(strTemp,m_vCmdStr[inum].c_str(),10);
  ToUpper(strTemp);  // 转换为大写来判断。
  if (strcmp(strTemp,"TRUE")==0) (*value)=true; 
  return true;
}

CCmdStr::~CCmdStr()
{
  m_vCmdStr.clear();
}

-----测试
// 用于存放足球运动员资料的结构体。
struct st_player
{
  char name[51];    // 姓名
  char no[6];       // 球衣号码
  bool striker;     // 场上位置是否是前锋,true-是;false-不是。
  int  age;         // 年龄
  double weight;    // 体重,kg。
  long sal;         // 年薪,欧元。
  char club[51];    // 效力的俱乐部
}stplayer;

int main()
{
  memset(&stplayer,0,sizeof(struct st_player));

  char buffer[301];  
  STRCPY(buffer,sizeof(buffer),"messi  ,10,true,30,68.5,2100000,Barcelona");

  CCmdStr CmdStr;
  CmdStr.SplitToCmd(buffer,",");        // 拆分buffer
  CmdStr.GetValue(0, stplayer.name,50); // 获取姓名
  CmdStr.GetValue(1, stplayer.no,5);    // 获取球衣号码
  CmdStr.GetValue(2,&stplayer.striker); // 场上位置
  CmdStr.GetValue(3,&stplayer.age);     // 获取年龄
  CmdStr.GetValue(4,&stplayer.weight);  // 获取体重
  CmdStr.GetValue(5,&stplayer.sal);     // 获取年薪,欧元。
  CmdStr.GetValue(6, stplayer.club,50); // 获取效力的俱乐部
  
  printf("name=%s,no=%s,striker=%d,age=%d,weight=%.1f,sal=%ld,club=%s\n",\
         stplayer.name,stplayer.no,stplayer.striker,stplayer.age,\
         stplayer.weight,stplayer.sal,stplayer.club);
  // 输出结果:name=messi,no=10,striker=1,age=30,weight=68.5,sal=21000000,club=Barcelona
}