MFC字符串类CString源代码
CString使⽤的是引⽤技术,可以共享数据(这个⼤家都知道),另外空的CStirng是指向⼀个固定的地址的(_afxInitData).另外CStirng是有长度限制的2147483647(⽆符号int 的最⼤值).
数据格式
struct CStringData
{
long nRefs; //引⽤记数
int nDataLength; //字符使⽤长度
int nAllocLength; //分配长度
TCHAR* data() { return (TCHAR*)(this+1); } //存放字符串的地⽅
//this+1 相当与是CStringData[1];所以TCHAR* data()指的是CStringData[1]的地址
};
基本和络通讯的数据包差不多
typedef struct tagAnsMarketData //统⼀的应答结构
{
WORD wStkNum; //数⽬
char iData[1]; //数据
}ANS_MARKET_DATA,*PANS_MARKET_DATA;
下⾯是代码了
#include <windows.h>
#include <assert.h>
#include <stdlib.h>
#include <malloc.h>
#include <tchar.h>
string.h
#ifndef __JONES__STRING__
#define __JONES__STRING__
struct CStringData
{
long nRefs; //引⽤记数
int nDataLength; //字符使⽤长度
int nAllocLength; //分配长度
TCHAR* data() { return (TCHAR*)(this+1); } //存放字符串的地⽅
//this+1 相当与是CStringData[1];所以TCHAR* data()指的是CStringData[1]的地址
};
class CString
{
public:
//构造函数
CString();
CString(const CString& stringSrc);
CString(TCHAR ch, int nLength =1);
CString(LPCTSTR lpsz); // CString(LPCSTR lpsz); ANSI下版本
//CString(LPCWSTR lpsz);UNICODE下版本
CString(LPCTSTR lpch, int nLength); //CString(LPCSTR lpch, int nLength);ANSI下版本 //CString(LPCWSTR lpch, int nLength);//UNICODE下版本
CString(const unsigned char* psz);
~CString();
//CStringData的属性
int GetLength() const; //得到字符长度
int GetAllocLength() const; //得到分配的内存长度
BOOL IsEmpty() const; //判断字符长度是否为0
operator LPCTSTR() const; //类型转换
void Empty(); //清空CStringData
//操作符重载
const CString& operator=(const CString& stringSrc);
const CString& operator=(LPCTSTR lpsz);
const CString& operator=(TCHAR ch);
const CString& operator+=(const CString& string);
const CString& operator+=(TCHAR ch);
const CString& operator+=(LPCTSTR lpsz);
TCHAR operator[](int nIndex) const;
friend CString operator+(const CString& string1,const CString& string2);
friend CString operator+(const CString& string, TCHAR ch);
friend CString operator+(TCHAR ch, const CString& string);
friend CString operator+(const CString& string, LPCTSTR lpsz);
friend CString operator+(LPCTSTR lpsz, const CString& string);
//操作,脱离共享数据块
int Delete(int nIndex, int nCount = 1);//删除从nIndex开始长度为nCount的数据
int Insert(int nIndex, TCHAR ch); //插⼊⼀个字符
int Insert(int nIndex, LPCTSTR pstr); //插⼊⼀个字符串
int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew); //替换数据
int Replace(TCHAR chOld, TCHAR chNew); //替换数据
int Remove(TCHAR chRemove); //移除⼀个字符
void TrimRight(LPCTSTR lpszTargetList);
void TrimRight(TCHAR chTarget);//去掉右边chTarget
void TrimRight(); //去掉右边空格
void TrimLeft(LPCTSTR lpszTargets);
void TrimLeft(TCHAR chTarget); //去掉左边chTarget
void TrimLeft(); //去掉左边空格
//取某段字符串
void SetAt(int nIndex, TCHAR ch);
TCHAR GetAt(int nIndex) const;
CString Mid(int nFirst) const; //取某段字符串
CString Mid(int nFirst, int nCount) const; //取某段字符串
CString Right(int nCount) const; //取右边字符串
CString Left(int nCount) const; //取左边字符串
void CString::MakeUpper(); //⼤写
void CString::MakeLower(); //⼩写
void CString::MakeReverse(); //不知道⼲什么的 strrev
/
/查
int Find(TCHAR ch) const;
int Find(TCHAR ch, int nStart) const;
int ReverseFind(TCHAR ch) const;
int Find(LPCTSTR lpszSub) const;
int Find(LPCTSTR lpszSub, int nStart) const;
int FindOneOf(LPCTSTR lpszCharSet) const;//得到第⼀个匹配lpszCharSet中其中⼀个字符的位置调⽤_tcspbrk //⾼级操作
LPTSTR GetBuffer(int nMinBufLength); //重新分配内存,在拷贝原来的数据
void ReleaseBuffer(int nNewLength=-1); //在[nNewLength]='/0',对内存⼤⼩没有改变
LPTSTR GetBufferSetLength(int nNewLength); //重新分配内存,在拷贝原来的数据
void FreeExtra(); //深拷贝⾃⼰,然后--原来的引⽤记数器
LPTSTR LockBuffer(); //引⽤计数器=-1,加锁
void UnlockBuffer(); //解锁,引⽤计数器=1
//⽐较
int Compare(LPCTSTR lpsz) const; //区分⼤⼩写⽐较
int CompareNoCase(LPCTSTR lpsz) const; //不区分⼤⼩写⽐较
//⽐较速度没有Compare快
int Collate(LPCTSTR lpsz) const; //区分⼤⼩写⽐较
int CollateNoCase(LPCTSTR lpsz) const; //不区分⼤⼩写⽐较
//格式化字符串
void Format(LPCTSTR lpszFormat, ...);//CSting中最长的函数了,完全是⾃⼰分析的(⽜啊)
private:
void Init();
CStringData* GetData() const; //通过m_pchData-1 得到CStringData
void AllocBuffer(int nLen); //给CStringData分配内存,不带记数器
void CopyBeforeWrite(); //带引⽤记数的复制⾃⼰深拷贝
void AllocBeforeWrite(int nLen); //给CStringData分配内存,带记数器
void AssignCopy(int nSrcLen, LPCTSTR lpszSrcData);//分配内存,并拷贝lpszSrcData内容
//把nCopyIndex开始的nCopyLen长度的数据拷贝给dest,nExtraLen扩充的长度,次函数好像没下⾯⽤ void AllocCopy(CString& dest, int nCopyLen, int nCopyIndex,int nExtraLen) const;
void Release(); //--引⽤记数器并判断是否删除内存,如删除并初始化
void FormatV(LPCTSTR lpszFormat, va_list argList);//格式化字符串
void ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data,
int nSrc2Len, LPCTSTR lpszSrc2Data);//连接数据lpszSrc1Data+lpszSrc2Data
void ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData); //连接字符串
static void Release(CStringData* pData); //--引⽤记数器并判断是否删除内存
static void FreeData(CStringData* pData); //释放内存
static int SafeStrlen(LPCTSTR lpsz); //得到长度
LPTSTR m_pchData; //指向CStringData的数据区
};
/*调⽤CString::Compare⽐较⼤⼩,如果⽐较中有CStirng的话⽤
调⽤operator LPCTSTR()转化类型为LPCTSTR
*/
bool operator==(const CString& s1, const CString& s2);
bool operator==(const CString& s1, LPCTSTR s2);
bool operator==(LPCTSTR s1, const CString& s2);
bool operator!=(const CString& s1, const CString& s2);
bool operator!=(const CString& s1, LPCTSTR s2);
bool operator!=(LPCTSTR s1, const CString& s2);
bool operator<(const CString& s1, const CString& s2);
bool operator<(const CString& s1, LPCTSTR s2);
bool operator<(LPCTSTR s1, const CString& s2);
bool operator>(const CString& s1, const CString& s2);
bool operator>(const CString& s1, LPCTSTR s2);
bool operator>(LPCTSTR s1, const CString& s2);
bool operator<=(const CString& s1, const CString& s2);
bool operator<=(const CString& s1, LPCTSTR s2);
bool operator<=(LPCTSTR s1, const CString& s2);
bool operator>=(const CString& s1, const CString& s2);
bool operator>=(const CString& s1, LPCTSTR s2);
bool operator>=(LPCTSTR s1, const CString& s2);
//
//检测lpsz是否有效,调⽤了IsBadStringPtr
BOOL AfxIsValidString(LPCTSTR lpsz, int nLength = -1);
//检测lp是否能读写权限,调⽤了IsBadReadPtr,IsBadStringPtr
BOOL AfxIsValidAddress(const void* lp,UINT nBytes, BOOL bReadWrite = TRUE);
//CStirng数组操作
void ConstructElements(CString* pElements, int nCount); //初始化CStirng数组
void DestructElements(CString* pElements, int nCount); //删除CStirng数组
void CopyElements(CString* pDest, const CString* pSrc, int nCount); //CString数组拷贝
#endif
string.cpp
#include "stdafx.h"
#include "string.h"
TCHAR afxChNil = '/0';
int _afxInitData[] = { -1, 0, 0, 0 }; //初始化CStringData的地址
CStringData* _afxDataNil = (CStringData*)&_afxInitData; //地址转化为CStringData* LPCTSTR _afxPchNil = (LPCTSTR)(((BYTE*)&_afxInitData)+sizeof(CStringData)); const CString& AfxGetEmptyString() //建⽴⼀个空的CString
{ return *(CString*)&_afxPchNil; }
BOOL AfxIsValidString(LPCTSTR lpsz, int nLength /* = -1 */)
{
if (lpsz == NULL)
return FALSE;
return ::IsBadStringPtr(lpsz, nLength) == 0;
}
BOOL AfxIsValidAddress(const void* lp, UINT nBytes,BOOL bReadWrite /* = TRUE */) {
return (lp != NULL && !IsBadReadPtr(lp, nBytes) &&
(!bReadWrite !IsBadWritePtr((LPVOID)lp, nBytes)));
}
void CString::Init()
{ m_pchData=AfxGetEmptyString().m_pchData; }
CString::CString()
{ Init(); }
int CString::GetLength() const
c++string类型{ return GetData()->nDataLength; }
int CString::GetAllocLength() const
{ return GetData()->nAllocLength; }
BOOL CString::IsEmpty() const
{ return GetData()->nDataLength == 0; }
CStringData* CString::GetData() const
{
assert(m_pchData != NULL);
return ((CStringData*)m_pchData)-1;
}
CString::operator LPCTSTR() const
{ return m_pchData; }
int CString::SafeStrlen(LPCTSTR lpsz)
{ return (lpsz == NULL) ? 0 : lstrlen(lpsz); }
void CString::AllocBuffer(int nLen)
{
assert(nLen >= 0);
assert(nLen <= 2147483647-1); // (signed) int 的最⼤值
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论