我花一些时间写了一个CString类.单从功能上也没什么就是实现了我们写程序常用的一些功能.我认为关键还是在你写的时候,在你脑海中出现的一些思想!
这个CString类实现了大部分MFC里的CString功能,并且基本上是用纯粹的C++语言来实现的.如果你仔细看的话,你应该可以学到有用的算法,数据结构 ,以及编程思想的.
好了,我就无私的给他贴出来啊.如果有兴趣,你也可以继续扩充.并且,我也留了一点故意不实现的.好,看代码吧.
首先是头文件:
#include "stdarg.h"
#include "TCHAR.H"
#include "iostream"
using namespace std;
#ifndef _STRING_H_H_
#define _STRING_H_H_
#ifndef NULL
#define NULL 0
#endif//NULL
#ifndef DEF_SIZE
#define DEF_SIZE 256
#endif//DEF_SIZE
/*------------------------------------------------*/
声明:
1、字符串默认空间大小256
2、字符串是基于0的索引
/*------------------------------------------------*/
class CString
{
public:
char * m_pStr;
int m_nLen;
int m_nMaxSize;
public:
/*------------------------------------------------*/
构造函数
/*------------------------------------------------*/
CString ( );
CString ( const char ch );
CString ( const char* pstr );
CString ( const CString &str );
/*------------------------------------------------*/
析构函数
/*------------------------------------------------*/
virtual ~CString( );
/*------------------------------------------------*/
向串尾追加数据,返回长度,否则-1
/*------------------------------------------------*/
int Append ( const char ch );
int Append ( const char *pstr );
int Append ( const CString &str );
/*------------------------------------------------*/
插入数据到串的一个位置,返回长度,否则-1
/*------------------------------------------------*/
int Insert ( const char ch,int pos );
int Insert ( const char *pstr,int pos );
int Insert ( const CString &str,int pos );
/*------------------------------------------------*/
删除数据,返回长度,否则-1
/*------------------------------------------------*/
int Remove ( int nStart, int nNum );
/*------------------------------------------------*/
截断数据,返回长度
/*------------------------------------------------*/
int Trim ( const char ch );
int Trim ( const char *pstr );
int TrimLeft ( const char ch );
int TrimLeft ( const char *pstr );
int TrimRight ( const char ch );
int TrimRight ( const char *pstr );
/*------------------------------------------------*/
查找数据,返回长度,否则-1
/*------------------------------------------------*/
int Find ( const char ch, int nStart = 0 );
int Find ( const char *pstr, int nStart = 0 );
/*------------------------------------------------*/
变换数据
/*------------------------------------------------*/
void MakeUpper ( );
void MakeLower ( );
void Reverse ( );
/*------------------------------------------------*/
反向查找数据,返回正向索引值,否则-1
/*------------------------------------------------*/
int ReverseFind ( const char ch, int nStart = 0 );
int ReverseFind ( const char *pstr, int nStart = 0 );
/*------------------------------------------------*/
设置和得到数据
/*------------------------------------------------*/
char GetAt ( int pos );
int SetAt ( int pos ,const char ch );
/*------------------------------------------------*/
替换数据
/*------------------------------------------------*/
int Replace ( const char ch1, const char ch2 );
/*
int Replace ( const char ch, const char *pstr );
int Replace ( const char *pstr1, const char *pstr2 );
int Replace ( const char *pstr, const char ch );
//呵呵,没有写了。谁有兴趣就写写哦!
*/
/*------------------------------------------------*/
其他
/*------------------------------------------------*/
int GetLength ( );
int GetBufferSize ( );
bool IsEmpty ( );
/*------------------------------------------------*/
清空数据,返回BUFFER大小
/*------------------------------------------------*/
int Clear();
/*------------------------------------------------*/
格式化数据
/*------------------------------------------------*/
void Format ( const char * pstrFormat, ... );
/*------------------------------------------------*/
操作符重载
/*------------------------------------------------*/
operator char * ();
operator const char * ();
void operator = ( const char ch );
void operator = ( const char * pstr );
void operator = ( const CString & str );
friend CString operator + ( const char ch, const CString & str );
friend CString operator + ( const char pstr[], const CString & str );
friend CString operator + ( const CString & str1, const CString & str2 );
void operator += ( const char ch );
void operator += ( const char pstr[] );
void operator += ( const CString &str );
char & operator []( int pos );
/*------------------------------------------------*/
输出重载
/*------------------------------------------------*/
friend ostream & operator << (ostream & out, CString & str );
//friend istream operator >> (istream &in, const CString & str );
};
#endif//_STRING_H_H_
然后是实现文件:
#include "String.h"
CString::CString( )
{
m_pStr = new char[DEF_SIZE];
memset( m_pStr, '/0', DEF_SIZE );
m_nLen = 0;
m_nMaxSize = DEF_SIZE;
}
CString::CString( const char ch )
{
m_pStr = new char[1 + DEF_SIZE];
memset( m_pStr, '/0', 1 + DEF_SIZE );
m_pStr[0] = ch;
m_nLen = 1;
m_nMaxSize = 1 + DEF_SIZE;
}
CString::CString( const char *pstr )
{
int i = 0,j = 0;
while( pstr != NULL && pstr[i] != '/0' ) i++;
j = i;
m_pStr = new char[i + DEF_SIZE];
memset( m_pStr, '/0', i + DEF_SIZE );
m_nMaxSize = i + DEF_SIZE;
for( ; i > 0 ; i-- )
{
m_pStr[i-1] = pstr[i-1];
}
m_nLen = j;
}
CString::CString( const CString &str )
{
int i = str.m_nLen;
m_pStr = new char[i + DEF_SIZE];
memset( m_pStr, '/0', i + DEF_SIZE );
m_nMaxSize = i + DEF_SIZE;
m_nLen = i;
for( ; i > 0 ; i-- )
{
m_pStr[i-1] = str.m_pStr[i-1];
}
}
CString::~CString( )
{
if( m_pStr != NULL )
{
delete [m_nMaxSize]m_pStr;
m_pStr = NULL;
}
m_nLen = 0;
m_nMaxSize = 0;
}
int CString::Append( const char ch )
{
if( m_nLen >= m_nMaxSize - 1 )
{
char *p = NULL;
p = (char*)realloc( m_pStr,DEF_SIZE + m_nMaxSize );
if( p == NULL ) return -1;
m_pStr = p;
memset( &p[m_nMaxSize], '/0', DEF_SIZE );
m_nMaxSize = DEF_SIZE + m_nMaxSize;
}
m_pStr[m_nLen++] = ch;
return m_nLen;
}
int CString::Append( const char *pstr )
{
if( pstr == NULL ) return -1;
int i = 0,j = 0;
char *p = NULL;
while( pstr[i] != '/0' ) i++;
j = i;
if( m_nLen + i > m_nMaxSize - 1 )
{
p = (char*)realloc( m_pStr,DEF_SIZE + i + m_nMaxSize );
if( p == NULL ) return -1;
m_pStr = p;
memset( &p[m_nMaxSize], '/0', DEF_SIZE + i );
m_nMaxSize = DEF_SIZE + i + m_nMaxSize;
}
for( i = m_nLen ; i < m_nLen + j ; i++ )
{
m_pStr[i] = pstr[ i - m_nLen ];
}
m_nLen += j;
return m_nLen;
}
int CString::Append( const CString & str )
{
int i = 0;
char *p = NULL;
if( m_nLen + str.m_nLen > m_nMaxSize - 1 )
{
p = (char*)realloc( m_pStr,DEF_SIZE + str.m_nLen + m_nMaxSize );
if( p == NULL ) return -1;
m_pStr = p;
memset( &p[m_nMaxSize], '/0', DEF_SIZE + str.m_nLen );
m_nMaxSize = DEF_SIZE + str.m_nLen + m_nMaxSize;
}
for( i = str.m_nLen; i > 0 ; i-- )
{
m_pStr[m_nLen + i - 1] = str.m_pStr[i - 1];
}
m_nLen += str.m_nLen;
return m_nLen;
}
int CString::Insert( const char ch,int pos )
{
if( pos < 0 || pos > m_nLen ) return -1;
char *p = NULL;
int i = 0;
if( m_nLen >= m_nMaxSize - 1 )
{
p = (char*)realloc( m_pStr, DEF_SIZE + m_nMaxSize );
if( p == NULL ) return -1;
m_pStr = p;
memset( &p[m_nMaxSize], '/0', DEF_SIZE );
m_nMaxSize = DEF_SIZE + m_nMaxSize;
}
for( i = m_nLen ; i > pos ; i-- )
{
m_pStr[i] = m_pStr[i - 1];
}
m_pStr[pos] = ch;
return ++m_nLen;
}
int CString::Insert( const char *pstr,int pos )
{
if( pstr == NULL || pos < 0 || pos > m_nLen ) return -1;
int i = 0,j = 0;
char * p = NULL;
while( pstr[i] != '/0' ) i++;
j = i;
if( m_nLen + i > m_nMaxSize - 1 )
{
p = (char*)realloc(m_pStr,DEF_SIZE + i + m_nMaxSize );
if( p == NULL ) return -1;
m_pStr = p;
memset(&p[m_nMaxSize],'/0',DEF_SIZE + i );
m_nMaxSize = DEF_SIZE + i + m_nMaxSize;
}
for( i = m_nLen ; i >= pos ; i-- )
{
m_pStr[i + j] = m_pStr[i];
}
for( i = 0 ; i < j ; i++ )
{
m_pStr[i + pos] = pstr[i];
}
m_nLen += j;
return m_nLen;
}
int CString::Insert( const CString & str,int pos )
{
if( pos < 0 || pos > m_nLen ) return -1;
char *p = NULL;
int i = 0;
if( m_nLen + str.m_nLen > m_nMaxSize - 1 )
{
p = (char*)realloc( m_pStr, DEF_SIZE + str.m_nLen + m_nMaxSize );
if( p == NULL ) return -1;
m_pStr = p;
memset( &p[m_nMaxSize], '/0', DEF_SIZE + str.m_nLen );
m_nMaxSize = DEF_SIZE + str.m_nLen + m_nMaxSize;
}
for( i = m_nLen ; i >= pos ; i-- )
{
m_pStr[i + str.m_nLen] = m_pStr[i];
}
for( i = 0 ; i < str.m_nLen ; i++ )
{
m_pStr[i + pos] = str.m_pStr[i];
}
m_nLen += str.m_nLen;
return m_nLen;
}
int CString::Remove( int nStart, int nNum )
{
if( nStart < 0 || nStart >= m_nLen || nStart + nNum > m_nLen ) return -1;
int i = 0,j = 0;
for( i = nStart + nNum,j = 0; i < m_nLen; i++,j++ )
{
m_pStr[nStart + j] = m_pStr[i];
}
m_nLen -= nNum;
m_pStr[m_nLen] = '/0';
return i;
}
int CString::Trim( const char ch )
{
int i = 0, j = 0;
int nNum = 0;
for ( i = 0, nNum = 0; i < m_nLen; i++ )
{
if ( m_pStr[i] == ch )
{
m_pStr[i] = '/0';
nNum++;
}
}
for ( i = 0,j = 0; i < m_nLen - nNum; i++,j++ )
{
if ( m_pStr[j] == '/0' )
{
do
{
j = j + 1;
} while( m_pStr[j] == '/0' && j < m_nLen );
if ( j >= m_nLen ) break;
}
if ( i != j )
{
m_pStr[i] = m_pStr[j];
}
}
m_nLen -= nNum;
memset( &m_pStr[m_nLen] , '/0', m_nMaxSize - m_nLen );
return m_nLen;
}
int CString::Trim( const char *pstr )
{
int i = 0,j = 0;
int nPos = 0,len = 0;
char * p = NULL;
while( pstr[i] != '/0' ) i++;
do
{
nPos = Find( pstr, nPos );
if ( nPos == -1 ) break;
memset( &m_pStr[nPos], '/0', i );
nPos++; j++;
} while( true );
len = m_nLen - i * j;
for ( i = 0,j = 0; i < len; i++,j++ )
{
if ( m_pStr[j] == '/0' )
{
do
{
j = j + 1;
} while( m_pStr[j] == '/0' && j < m_nLen );
if ( j >= m_nLen ) break;
}
if ( i != j )
{
m_pStr[i] = m_pStr[j];
}
}
m_nLen = len;
memset( &m_pStr[m_nLen] , '/0', m_nMaxSize - m_nLen );
return m_nLen;
}
int CString::TrimLeft( const char ch )
{
int i = 0,j = 0;
for( i = 0; i < m_nLen; i++ )
{
if ( m_pStr[i] != ch )
break;
}
if ( i > 0 )
{
for( j = i; j < m_nLen; j++ )
{
m_pStr[j - i] = m_pStr[j];
}
m_nLen -= i;
memset( &m_pStr[m_nLen] , '/0', m_nMaxSize - m_nLen );
}
return m_nLen;
}
int CString::TrimLeft( const char *pstr )
{
int i = 0,j = 0;
int len = 0;
while( pstr[len] != '/0' ) len++;
if ( len > m_nLen ) return m_nLen;
for( i = 0,j = 0; j < m_nLen; i++,j++ )
{
if( i >= len ) i = 0;
if ( m_pStr[j] != pstr[i] ) break;
}
if ( j > len )
{
i = j / len * len;
for( j = i; j < m_nLen; j++ )
{
m_pStr[j - i] = m_pStr[j];
}
m_nLen -= i;
memset( &m_pStr[m_nLen] , '/0', m_nMaxSize - m_nLen );
}
return m_nLen;
}
int CString::TrimRight( const char ch )
{
int i = 0, j = 0;
for( i = m_nLen - 1; i >= 0; i-- )
{
if ( m_pStr[i] != ch )
break;
}
m_nLen -= ( m_nLen - (i + 1) );
memset( &m_pStr[m_nLen] , '/0', m_nMaxSize - m_nLen );
return m_nLen;
}
int CString::TrimRight( const char *pstr )
{
int i = 0,j = 0;
int len = 0;
while( pstr[len] != '/0' ) len++;
if ( len > m_nLen ) return m_nLen;
for( i = len - 1,j = m_nLen - 1; j >= 0; i--,j-- )
{
if( i < 0 )
{
memset( &m_pStr[j + 1], '/0', len );
m_nLen -= len;
i = len - 1;
}
if ( m_pStr[j] != pstr[i] ) break;
}
return m_nLen;
}
int CString::Find( const char ch,int nStart )
{
int i ;
for( i = nStart ; i < m_nLen ; i++ )
{
if( m_pStr[i] == ch ) return i;
}
return -1;
}
int CString::Find( const char *pstr,int nStart )
{
int i = 0,j = -1;
int len = 0;
while( pstr[len] != '/0' ) len++;
int *next = new int[len];
next[0] = -1;
while( i < len - 1 )
{
if( j == -1 || pstr[i] == pstr[j] )
{
i++;
j++;
next[i] = j;
}
else
{
j = next[j];
}
}
i = nStart; j = 0;
while( i < m_nLen && j < len )
{
if( j == -1 || m_pStr[i] == pstr[j] )
{
i++;
j++;
}
else
{
j = next[j];
}
}
delete [len]next;
if( j >= len )
return i - len;
else
return -1;
}
void CString::MakeUpper( )
{
for( int i = 0; i < m_nLen ; i++ )
{
if( m_pStr[i] >= 'a' && m_pStr[i] <= 'z' ) m_pStr[i] -= 32;
}
}
void CString::MakeLower( )
{
for( int i = 0; i < m_nLen ; i++ )
{
if( m_pStr[i] >= 'A' && m_pStr[i] <= 'Z' ) m_pStr[i] += 32;
}
}
void CString::Reverse( )
{
char ch;
int i,j;;
for( i = 0,j = m_nLen - 1; i < j ; i++,j-- )
{
ch = m_pStr[i];
m_pStr[i] = m_pStr[j];
m_pStr[j] = ch;
}
}
int CString::ReverseFind( const char ch,int nStart )
{
int i;
for( i = m_nLen - 1; i >= 0 ; i-- )
{
if(m_pStr[i] == ch ) return i;
}
return -1;
}
int CString::ReverseFind( const char *pstr,int nStart )
{
int i,j;
int len = 0;
while( pstr[len] != '/0' ) len++;
i = m_nLen - 1;
j = len - 1;
int k = 0 ;
while( i >= 0 && j >= 0 )
{
if( m_pStr[ i - k ] == pstr[j] )
{
k++;
j--;
}
else
{
i--;
k = 0;
j = len - 1;
}
}
if( j < 0 )
return i - k + 1;
else
return -1;
}
char CString::GetAt( int pos )
{
return m_pStr[pos];
}
int CString::SetAt( int pos ,const char ch )
{
if ( pos < 0 || pos >= m_nLen ) return -1;
m_pStr[pos] = ch;
return m_nLen;
}
int CString::Replace( const char ch1, const char ch2 )
{
int i = 0;
for ( ; i < m_nLen; i++ )
{
if( m_pStr[i] == ch1 )
m_pStr[i] = ch2;
}
return m_nLen;
}
int CString::GetLength( )
{
return m_nLen;
}
int CString::GetBufferSize( )
{
return m_nMaxSize;
}
bool CString::IsEmpty( )
{
return m_nLen == 0;
}
int CString::Clear()
{
memset( m_pStr, '/0', m_nMaxSize );
m_nLen = 0;
return m_nMaxSize;
}
void CString::Format( const char * pstrFormat, ... )
{
//由于没有更新SDK所以,不能实现任意长度的格式化。
char buffer[1024] = {0};
va_list pArg;
va_start( pArg, pstrFormat );
_vstprintf( buffer, pstrFormat, pArg );
va_end( pArg );
*this = buffer;
}
CString::operator char * ( )
{
return m_pStr;
}
CString::operator const char * ( )
{
return (const char *)m_pStr;
}
void CString::operator = ( const char ch )
{
memset( m_pStr,'/0',m_nMaxSize );
m_nLen = 1;
m_pStr[0] = ch;
}
void CString::operator =( const char * pstr )
{
int i = 0,j = 0;
while( pstr != NULL && pstr[i] != '/0' ) i++;
j = i;
if( i >= m_nMaxSize )
{
delete [m_nMaxSize]m_pStr;
m_pStr = NULL;
m_pStr = new char[i + DEF_SIZE];
m_nMaxSize = i + DEF_SIZE;
}
memset( m_pStr, '/0', m_nMaxSize );
for( ; i > 0; i-- )
{
m_pStr[i - 1] = pstr[i - 1];
}
m_nLen = j;
}
void CString::operator =( const CString & str )
{
int i;
if( str.m_nLen >= m_nMaxSize )
{
delete [m_nMaxSize]m_pStr;
m_pStr = NULL;
m_pStr = new char[str.m_nMaxSize];
m_nMaxSize = str.m_nMaxSize;
}
memset( m_pStr, '/0', m_nMaxSize );
for( i = 0; i < str.m_nLen; i++ )
{
m_pStr[i] = str.m_pStr[i];
}
m_nLen = str.m_nLen;
}
CString operator + ( const char ch, const CString & str )
{
CString Str(ch);
Str.Append(str);
return Str;
}
CString operator + ( const char pstr[], const CString & str )
{
CString Str(pstr);
Str.Append(str);
return Str;
}
CString operator + ( const CString & str1, const CString & str2 )
{
CString Str(str1);
Str.Append(str2);
return Str;
}
void CString::operator += ( const char ch )
{
Append(ch);
}
void CString::operator += ( const char pstr[] )
{
Append(pstr);
}
void CString::operator += ( const CString &str )
{
Append(str);
}
char & CString::operator [] ( int pos )
{
return m_pStr[pos];
}
ostream & operator << (ostream &out, CString & str )
{
int i = 0,j = str.GetLength();
for( ; i < j; i++ )
out << str[i];
return out;
}
最后是测试文件,这里我只是简单的测试了一下,有可能有问题的.如果有,记得告诉我哦.
void main()
{
CString str1("11111");
CString str2 = "22222";
CString str3 = str2 + "33333";
CString str4;
str4 = "44444" + str3;
cout << str1 << endl;
cout << (char*)str2 << endl;
cout << (const char * )str3 << endl;
cout << str4 << endl;
str1.Append( '1' );
str2.Append( "22" );
str3.Append( str1 );
cout << str1 << endl;
cout << str2 << endl;
cout << str3 << endl;
cout << endl;
cout << str1;
cout << str1.GetAt(0) << endl;
str1[0] = '0';
cout << str1[0] << endl;
str1 += "00000";
cout << str1 << endl;
str1 = "111111";
cout << str1 << endl;
str2.Format( "%s%s%d%f","12345",",",100,100.0000000 );
cout << str2 << endl;
cout << str3 << endl;
cout << str3.Find( "11", 1 ) << endl;
char ch = str3[0];
cout << ch << endl;
ch = '9';
cout << str3[0] << endl;
str3.SetAt( 0, '0' );
cout << str3 << endl;
cout << str4 << endl;
cout << str4.ReverseFind( "44" , 0 ) << endl;
cout << str4.ReverseFind( '3', 0 ) << endl;
for( int i = 0; i < 100000; i++ )
str1 += "beyond";
// str1.MakeUpper();
// cout << str1 << endl;
for( i = 0 ; i < str1.GetLength(); i++ )
{
str1[i] = 'y';
}
str1.Clear();
cout << str1.IsEmpty() << endl;
CString str5(str1);
str5 = str4;
cout << str5 << endl;
/* cout << str3 << endl;
str3.TrimLeft('0');
cout << str3 << endl;
str3.TrimLeft( "22" );
cout << str3 << endl;
str3 = "1010102030401020032010";
cout << str3 << endl;
str3.Trim( "10" );
cout << str3 << endl;*/
/* cout << str3 << endl;
str3.TrimRight("11");
cout << str3 << endl;
str3.TrimRight( "3" );
cout << str3 << endl;
str1 = '2';
str3.Trim( str1 );
cout << str3 << endl;*/
char * p = str3;,
p[2] = 65;
cout << p << endl;
cout << str3 << endl;
}
好了,搞定!BYE!