C++下操作字符串的超级容易类~~~~~

类别:VC语言 点击:0 评论:0 推荐:

日记:
    今天我做了一个类。类的名字叫JString。是用来对字符串进行常规的操作的。
这个类的特点是,几乎所有的JString都用JString&的形式引用。
来源于托管内存管理式的思想,做到变量能自由创建和释放。
创建出来的所有对象会自动释放。所以一行内要多长就可以写多长。~~
以后不需要手工分配buffer了。。~~~~
我的水平不高。希望高手指正。

下载的地方是:
http://www.lostinet.com/public/cplusplus/jstring/
http://www.lostinet.com/public/cplusplus/jstring/jstring.cpp.txt
http://www.lostinet.com/public/cplusplus/jstring/jstring.zip

相关CSDN论坛文章:
http://www.csdn.net/expert/topic/984/984638.xml?temp=.7542993

 

// TestLib.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

/****************************************************************\
 链式委托内存管理的字符串类JString
 栈头堆尾?
 by- http://www.lostinet.com
 作者:Lostinet[迷失网络]。。(记得记住我啊。。)
\****************************************************************/

#ifndef _Lostinet_class_JString_
#define _Lostinet_class_JString_

/*
因为我是JScript的爱好者,并且很依赖JScript中的String类型
所以这个命名为JString了

工作原理:
在函数内定义一个由Stack分配的JString对象。
那么在函数返回的时候,JString对象就会释放。
JString对象对其所有操作所产生的对象,用一条链连起来。
那么当Stack生成的的JString对象释放时,
也自动释放其相关的所有JString了。
所以在类外部使用JString*指针是错误的用法
而且一条链中的对象最好不要传递到其他函数中。

通常的方法是在一个函数里定义第一个
JString js;
然后其它变量使用JString&类型

不建议在调用函数时传递JString*,和JString&

忠告:
在外面使用JString* 类型是不合法的。
千万要注意链的生存期,
特别是不同一条链的JString&+JString&时,返回的JString&属于第一条链

*/
#include <stdlib.h>
#include <string.h>
class JString
{
protected:
 JString* pAllocator;
 JString* pNext;
 //只有链头才用pLast
 JString* pLast;
 char* pString;
 int length;
 JString(JString& pA,unsigned int initLen=0,const char* initStr="")
 {
  pAllocator=&pA;
  if(pA.pLast)pA.pLast->pNext=this;
  pA.pLast=this;
  pNext=pLast=0;
  length=initLen;
  pString=new char[initLen+1];
  strcpy(pString,initStr);
 }

public:
 JString(const char* str)
 {
  pAllocator=this;
  pNext=pLast=0;
  length=strlen(str);
  pString=new char[length+1];
  strcpy(pString,str);
 }
 JString()
 {
  pAllocator=this;
  pNext=pLast=0;
  pString=new char[1];
  pString[0]=0;
  length=0;
 }
 virtual ~JString()
 {
  delete pString;
  if(pNext)delete pNext;
 }
 char* Detach()
 {
  char* str=pString;
  pString=new char[1];
  pString[0]=0;
  length=0;
  return str;
 }
 char* GetBuffer()
 {
  return pString;
 }
 char* GetBufferSetLength(int len)
 {
  //assert(len>=0);
  delete pString;
  length=len;
  pString=new char[len+1];
  return pString;
 }

/****************************************************************/

 int GetLength()
 {
  return length;
 }
 int IndexOf(const char * str,int start=0)
 {
  if(start+1>length)return -1;
  char* pStart=pString+start;
  char* pos=strstr(pStart,str);
  if(pos==0)return -1;
  return pos-pString;
 }
 int LastIndexOf(const char * str)
 {
  int len=strlen(str);
  char *buf1=new char[length+1];
  char *buf2=new char[len+1];
  strcpy(buf1,pString);
  strcpy(buf2,str);
  strrev(buf1);
  strrev(buf2);
  char* pos=strstr(buf1,buf2);
  delete buf1;
  delete buf2;
  if(pos==0)return -1;
  return length+buf1-pos-len;
 }

 JString& Left(int len)
 {
  return Substr(0,len);
 }
 JString& Right(int len)
 {
  return Substr(length-len,len);
 }

 JString& Substr(int start,int len)
 {
  if(start<0)start=0;
  if(start+1>length)
   return * new JString(*pAllocator);
  if(len<=0)
   return * new JString(*pAllocator);
  if(start+len>length)
   len=length-start;
  char* buf=new char[len+1];
  memcpy(buf,pString+start,len);
  buf[len]=0;
  JString* pStr=new JString(*pAllocator,len,buf);
  delete buf;
  return * pStr;
 }

 JString& Lower()
 {
  JString* pStr=new JString(*pAllocator);
  strcpy(pStr->GetBufferSetLength(length),pString);
  strlwr(pStr->GetBuffer());
  return * pStr;
 }

 JString& Upper()
 {
  JString* pStr=new JString(*pAllocator);
  strcpy(pStr->GetBufferSetLength(length),pString);
  strupr(pStr->GetBuffer());
  return * pStr;
 }
/****************************************************************/

 double Number()
 {
  return strtod(pString,0);
 }

 JString& Convert(bool b)
 {
  return * new JString(*pAllocator,b?4:5,b?"true":"false");
 }
 JString& Convert(double d)
 {
  char buf[64];
  sprintf(buf,"%g",d);
  return * new JString(*pAllocator,strlen(buf),buf);
 }
 JString& Convert(int n)
 {
  char buf[64];
  sprintf(buf,"%d",n);
  return * new JString(*pAllocator,strlen(buf),buf);
 }
 JString& Convert(const char* str)
 {
  return * new JString(*pAllocator,strlen(str),str);
 }

/****************************************************************/

 //所有的char*输入,地址都必须不为0

 JString& operator + (JString& Str)
 {
  //if(Str.pAllocator!=pAllocator)throw("JString& operator + (JString& Str) 不能使用不同一条链的对象");
  //注意:两条链的元素相加,返回的元素属于第一条链
  JString* pRes=new JString(*pAllocator,length+Str.length,pString);
  strcat(pRes->pString,Str.pString);
  return *pRes;
 }
 JString& operator + (const char* str)
 {
  JString* pRes=new JString(*pAllocator,length+strlen(str),pString);
  strcat(pRes->pString,str);
  return *pRes;
 }
 JString& operator + (bool b)
 {
  JString* pStr=new JString(*pAllocator,length+(b?4:5),pString);
  strcat(pStr->pString,(b?"true":"false"));
  return *pStr;
 }
 JString& operator + (double d)
 {
  char buf[64];
  sprintf(buf,"%g",d);
  return *this+buf;
 }
 JString& operator + (int n)
 {
  char buf[64];
  sprintf(buf,"%d",n);
  return *this+buf;
 }
 JString& operator += (bool b)
 {
  *this+=b?"true":"false";
  return *this;
 }
 JString& operator += (double d)
 {
  char buf[64];
  sprintf(buf,"%g",d);
  *this+=buf;
  return *this;
 }
 JString& operator += (int n)
 {
  char buf[64];
  sprintf(buf,"%d",n);
  *this+=buf;
  return *this;
 }
 JString& operator += (const char *str)
 {
  length=length+strlen(str);
  char* pStr=new char[length+1];
  strcpy(pStr,pString);
  strcat(pStr,str);
  delete pString;
  pString=pStr;
  return *this;
 }
 JString& operator = (bool b)
 {
  if(b)
   *this="true";
  else
    *this="false";
  return *this;
 }
 JString& operator = (double d)
 {
  char buf[64];
  sprintf(buf,"%g",d);
  *this=buf;
  return *this;
 }
 JString& operator = (int n)
 {
  char buf[64];
  sprintf(buf,"%d",n);
  *this=buf;
  return *this;
 }
 JString& operator = (JString& Str)
 {
  delete pString;
  length=Str.length;
  pString=new char[length+1];
  strcpy(pString,Str.pString);
  return *this;
 }
 JString& operator = (const char* str)
 {
  delete pString;
  length=strlen(str);
  pString=new char[length+1];
  strcpy(pString,str);
  return *this;
 }

/****************************************************************/

 bool CompareNoCase(const char* str)
 {
  return strcmpi(pString,str)==0;
 }

 bool operator == (const char* str)
 {
  return strcmp(pString,str)==0;
 }
 bool operator == (int n)
 {
  char buf[64];
  sprintf(buf,"%d",n);
  return *this==buf;
 }
 bool operator == (double d)
 {
  char buf[64];
  sprintf(buf,"%g",d);
  return *this==buf;
 }

/****************************************************************/

 operator bool ()
 {
  return length>0?true:false;
 }

 operator const char* ()
 {
  return pString;
 }
};
template <class T>
JString& operator + (T t,JString& js)
{
 return js.Convert(t)+js;
}
template <class T>
JString& operator == (T t,JString& js)
{
 return js==t;
}

#endif //_Lostinet_class_JString_


#include "iostream.h"
int main(int argc, char* argv[])
{
 //假如在某个地方得到szURL
// const char* szURL="http://www.lostinet.com/some.asp";
// const char* szURL="http://www.lostinet.com/some.asp?id=35&style=1";
 const char* szURL="http://www.lostinet.com/some.asp?id=35&page=3&style=1&page=5";

 //现在目标是解析那段字符串,把page=3中的3取出来,默认为1
 //如果是一般的操作,那么需要很长的代码
 //注意,这个过程没有显式地分配buffer
 //除去注释,不计较szURL,那么一共定义了四个变量
 //其中字符先相关的是 JString jsURL 和 JString& jsParams
 //代码共22行(包括3个{和3个})

 int page=1;
 JString jsURL(szURL);
 //搜索URL中?号的地方。如果没有问号,代表没有参数
 int pos=jsURL.IndexOf("?");
 if(pos>-1)//IndexOf返回-1代表搜索不到"?",没有参数
 {
  //JString& jsParams= 是取得新的JString对象的引用
  //pos+1是为了Substr得到的不包括pos所在的"?"
  //jsURL.GetLength()是jsURL的长度,Substr自动识别长度。取到字符串最后
  //Lower()得到小写,非正规写法是strlwr(jsParams.GetBuffer());
  JString& jsParams=jsURL.Substr(pos+1,jsURL.GetLength()).Lower();
  
  //重载了 (bool) 操作符,意思是while(jsParams.GetLength()>1)
  while(jsParams)
  {
   //开始寻找"page="的下落
   pos=jsParams.IndexOf("page=");
   //找不到"page="当然退出了
   if(pos==-1)
    break;
   //0是因为jsParams第一项就是page=....
   //不是0的情况应该继续
   if(pos==0)
   {
    //去掉"page="然后得到后面的数字
    // JString("3&style=1&page=5") 的.Number() 是 3
    page=jsParams.Substr(5,jsParams.GetLength()).Number();
    break;//不break的话,就会继续搜索。在例子中,取得page=5
   }
   //找URL参数分割符
   pos=jsParams.IndexOf("&");
   //如果没有分割符了,代表这次的jsParams是最后一个了。
   if(pos==-1)
    break;
   //"id=35&page=3&style=1&page=5"=>"page=3&style=1&page=5"
   //如此类推
   jsParams=jsParams.Substr(pos+1,jsParams.GetLength());
  }
 }
 cout<<page;

 //性能参考:
 //例子代码运行后,JString对象一共分配4个,每个占20BYTE的内存。jsURL是第一个
 //过程是:
 //1 JString() : JString jsURL(szURL);
 //2 Substr() : JString& jsParams=jsURL.Substr(pos+1,jsURL.GetLength()).Lower();
 //3 Lower()  : 同上
 //4 Substr() : jsParams=jsParams.Substr(pos+1,jsParams.GetLength());
 //5 Substr() : page=jsParams.Substr(5,jsParams.GetLength()).Number();
 //
 //如果把 break;//不break的话,就会继续搜索。在例子中,取得page=5
 //去掉,那么JString对象一共分配8个。
 //因为多了两次的jsParams=jsParams.Substr(pos+1,jsParams.GetLength());
 //
 //JString必须等其链头所在的函数退出,整条链才会释放。
 //如果一个函数长期不退出,不断地计算字符串,
 //那么要确定操作数量不多(10000次的+操作也不算多,100000次就很多了),
 //那才考虑使用JString
 //

 cout<<"\n\n\n\n";
 return 0;
}

 

 

-----------------------------------------------------------

例子去掉注释后:

#include "iostream.h"
int main(int argc, char* argv[])
{
 const char* szURL="http://www.lostinet.com/some.asp?id=35&page=3&style=1&page=5";

 int page=1;
 JString jsURL(szURL);
 int pos=jsURL.IndexOf("?");
 if(pos>-1)
 {
  JString& jsParams=jsURL.Substr(pos+1,jsURL.GetLength()).Lower();  
  while(jsParams)
  {
   pos=jsParams.IndexOf("page=");
   if(pos==-1)
    break;
   if(pos==0)
   {
    page=jsParams.Substr(5,jsParams.GetLength()).Number();
    break;
   }
   pos=jsParams.IndexOf("&");
   if(pos==-1)
    break;
   jsParams=jsParams.Substr(pos+1,jsParams.GetLength());
  }
 }
 cout<<page;
 cout<<"\n\n\n\n";
 return 0;
}

 

本文地址:http://com.8s8s.com/it/it2325.htm