参考了C++Builder中的AnsiString, 实现了常用的功能,其它需要的可以自己添加.
/* CesString.h
* 类似AnsiString 的一个类, 用标准C++编写, 可以用在VC和CB中
* 作者: cczlp
*/
#ifndef _CESSTRING_H_
#define _CESSTRING_H_
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
namespace CESSTRING
{
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
class CesString
{
private:
struct StrRec
{
UINT m_uBufferLen;
UINT m_uStringLen;
};
LPTSTR m_pszText;
protected:
void __fastcall AllocateBuffer(const UINT uLen, bool bRealloc = false)
{
UINT uTotalLen = sizeof(StrRec) + (uLen + 1) * sizeof(TCHAR);
StrRec *pStrRec;
if (bRealloc && m_pszText != NULL)
{
char *pData = (char *) & GetRec();
pStrRec = (StrRec *)realloc(pData, uTotalLen);
if (uLen < Length())
{
pStrRec->m_uStringLen = uLen;
}
}
else
{
pStrRec = (StrRec *)malloc(uTotalLen);
pStrRec->m_uStringLen = 0;
}
pStrRec->m_uBufferLen = uLen;
m_pszText = (TCHAR *)(pStrRec + 1);
if (!bRealloc)
{
m_pszText[0] = _T('\0'); // no characters yet so set first to 0
}
m_pszText[uLen] = _T('\0'); // set last character in buffer to 0
}
void __fastcall SafeDelete()
{
if (m_pszText != NULL)
{
free((char *)&GetRec());
m_pszText = NULL;
}
}
public:
CesString() : m_pszText(NULL)
{};
CesString(const CesString & src)
{
AllocateBuffer(src.Length());
GetRec().m_uStringLen = src.Length();
lstrcpy(m_pszText, src.m_pszText);
};
CesString(LPCTSTR pszSrc, UINT uLen = 0)
{
UINT uSrcLen = lstrlen(pszSrc);
UINT uBufLen = uLen == 0 ? uSrcLen : uLen;
AllocateBuffer(uBufLen);
GetRec().m_uStringLen = min(uSrcLen, uBufLen);
memcpy(m_pszText, pszSrc, GetRec().m_uStringLen * sizeof(TCHAR));
m_pszText[GetRec().m_uStringLen] = _T('\0');
};
~CesString()
{
SafeDelete();
};
public:
StrRec & __fastcall GetRec() const
{
return reinterpret_cast<StrRec *>(m_pszText)[-1];
};
UINT __fastcall Length() const
{
return m_pszText != NULL ? GetRec().m_uStringLen : 0;
};
inline void __fastcall SetTextLength(UINT uLen) const
{
GetRec().m_uStringLen = uLen;
m_pszText[uLen] = _T('\0');
}
// C string operator
TCHAR* __fastcall c_str() const
{
return (m_pszText) ? m_pszText : _T("");
}
bool __fastcall IsEmpty() const
{
return m_pszText == NULL;
}
// Modify string
CesString & __fastcall Insert(const CesString& str, UINT uIndex)
{
if (uIndex < 1 || uIndex > Length())
{
throw ;
}
UINT uStrLen = lstrlen(str);
UINT uSrcLen = Length();
UINT uPos = uIndex - 1;
this->AllocateBuffer(uStrLen + uSrcLen, true);
memmove(m_pszText + uPos + uStrLen, m_pszText + uPos, uSrcLen - uPos);
memcpy(m_pszText + uPos, str.m_pszText, uStrLen);
SetTextLength(uStrLen + uSrcLen);
return *this;
}
CesString& __fastcall Delete(UINT uIndex, UINT count)
{
UINT uPos = uIndex - 1;
if (uIndex < 1 || uPos + count > Length())
{
throw "";
}
if (uPos + count == Length())
{
SetLength(uPos);
}
else
{
memmove(m_pszText + uPos, m_pszText + uPos + count, Length() - uPos - count);
SetTextLength(Length() - count);
}
return *this;
}
CesString& __fastcall SetLength(UINT uNewLength)
{
UINT uOldLen = Length();
if (uNewLength > 0)
{
AllocateBuffer(uNewLength, true);
SetTextLength(min(uOldLen, uNewLength));
}
else
{
SafeDelete();
}
return *this;
}
int __fastcall Pos(const CesString& subStr) const
{
LPTSTR pszPosition; // Marks where the string was found
pszPosition = _tcsstr(m_pszText, subStr.m_pszText); // find string
return (pszPosition == NULL) ? 0 : (pszPosition - m_pszText + 1);
}
CesString __fastcall LowerCase() const
{
CesString tmp(*this);
_tcslwr(tmp.m_pszText);
return tmp;
}
CesString __fastcall UpperCase() const
{
CesString tmp(*this);
_tcsupr(tmp.m_pszText);
return tmp;
}
CesString __fastcall Trim() const
{
TrimLeft();
TrimRight();
return *this;
}
CesString __fastcall TrimLeft() const
{
CesString tmp(*this);
UINT uDel = 0;
LPSTR pDat = tmp.m_pszText;
while (*pDat && _istspace(*pDat++));
uDel = pDat - tmp.m_pszText - 1;
if (uDel > 0)
{
tmp.Delete(1, uDel);
}
return tmp;
}
CesString __fastcall TrimRight() const
{
CesString tmp(*this);
UINT uDel = 0;
LPSTR pDat = tmp.m_pszText + tmp.Length() - 1;
LPSTR pStart = pDat;
while (pDat >= tmp.m_pszText && _istspace(*pDat--));
uDel = pStart - pDat;
if (uDel > 0)
{
tmp.SetLength(tmp.Length() - uDel);
}
return tmp;
}
CesString __fastcall SubString(UINT index, UINT count) const
{
CesString tmp;
tmp.SetLength(count);
memcpy(tmp.m_pszText, m_pszText + index - 1, count);
return tmp;
}
int __fastcall ToInt() const
{
TCHAR* pStop = NULL;
int nBase = 10;
if (Length() > 2 && m_pszText[0] == _T('\0')
&& (m_pszText[1] == _T('x') || m_pszText[1] == _T('X')))
{
nBase = 16 ;
}
long lValue = _tcstol(m_pszText, &pStop, nBase);
if (errno == ERANGE || *pStop != _T('\0'))
{
throw ;
}
return lValue;
}
int __fastcall ToIntDef(int defaultValue) const
{
char* pStop = NULL;
int nBase = 10;
if (Length() > 2 && m_pszText[0] == _T('\0')
&& (m_pszText[1] == _T('x') || m_pszText[1] == _T('X')))
{
nBase = 16 ;
}
long lValue = _tcstol(m_pszText, &pStop, nBase);
if (errno == ERANGE || *pStop != _T('\0'))
{
return defaultValue;
}
return lValue;
}
double __fastcall ToDouble() const
{
char* pStop = NULL;
double dValue = _tcstod(m_pszText, &pStop);
if (errno == ERANGE || *pStop != _T('\0'))
{
throw;
}
return dValue;
}
#undef vprintf
#undef printf
#undef sprintf
int __cdecl CesString::vprintf(LPCTSTR format, va_list paramList)
{
int size = _vsntprintf(NULL, 0, format, paramList);
SetLength(size);
return _vsntprintf(m_pszText, size + 1, format, paramList);
}
int __cdecl CesString::cat_vprintf(LPCTSTR format, va_list paramList)
{
int size = _vsntprintf(NULL, 0, format, paramList);
int len = Length();
SetLength(len + size);
return _vsntprintf(m_pszText + len, size + 1, format, paramList);
}
int __cdecl CesString::printf(LPCTSTR format, ...)
{
int rc;
va_list paramList;
va_start(paramList, format);
rc = _vtprintf(format, paramList);
va_end(paramList);
return rc;
}
CesString& __cdecl CesString::sprintf(LPCTSTR format, ...)
{
va_list paramList;
va_start(paramList, format);
_vtprintf(format, paramList);
va_end(paramList);
return *this;
}
int __cdecl CesString::cat_printf(LPCTSTR format, ...)
{
int rc;
va_list paramList;
va_start(paramList, format);
rc = cat_vprintf(format, paramList);
va_end(paramList);
return rc;
}
CesString& __cdecl CesString::cat_sprintf(LPCTSTR format, ...)
{
va_list paramList;
va_start(paramList, format);
cat_vprintf(format, paramList);
va_end(paramList);
return *this;
}
public:
operator LPCTSTR() const
{
return m_pszText;
} // pointer to string
const CesString& operator= (LPCTSTR pszText) // Set a new text
{
UINT uTextLen = lstrlen(pszText);
SafeDelete();
AllocateBuffer(uTextLen);
lstrcpy(m_pszText, pszText);
GetRec().m_uStringLen = uTextLen;
return *this;
}
const CesString& operator= (const CesString &Str) // Set a new text
{
SafeDelete();
AllocateBuffer(Str.Length());
lstrcpy(m_pszText, Str.m_pszText);
GetRec().m_uStringLen = Str.Length();
return *this;
}
const CesString& operator+=(LPCTSTR pszText) // Add a text
{
UINT uTextLen = lstrlen(pszText);
UINT uTotalLen = GetRec().m_uStringLen + uTextLen;
AllocateBuffer(uTotalLen, true);
GetRec().m_uStringLen = uTotalLen;
lstrcat(m_pszText, pszText);
return *this;
}
const CesString& operator+=(CesString Str) // Add a text
{
return operator+=(Str.m_pszText);
}
const CesString operator+(LPCTSTR pszText) // Add a text
{
CesString tmp(m_pszText);
tmp += pszText;
return tmp;
}
const CesString operator+(CesString Str) // Add a text
{
CesString tmp(m_pszText);
tmp += Str.m_pszText;
return tmp;
}
// Comparisons
bool operator ==(const CesString& Str) const
{
return _tcscmp(m_pszText, Str.m_pszText) == 0;
}
bool operator !=(const CesString& Str) const
{
return _tcscmp(m_pszText, Str.m_pszText) != 0;
}
bool operator <(const CesString& Str) const
{
return _tcscmp(m_pszText, Str.m_pszText) < 0;
}
bool operator >(const CesString& Str) const
{
return _tcscmp(m_pszText, Str.m_pszText) > 0;
}
bool operator <=(const CesString& Str) const
{
return _tcscmp(m_pszText, Str.m_pszText) <= 0;
}
bool operator >=(const CesString& Str) const
{
return _tcscmp(m_pszText, Str.m_pszText) >= 0;
}
TCHAR& operator [](const UINT idx)
{
if (idx < 1 || idx > Length())
{
throw;
}
return m_pszText[idx-1];
}
};
}
using namespace CESSTRING;
#endif //_CESSTRING_H_