Hello, Community
During the last few days, I've been writing a string class for c++.
This is only as an experiment to see if it can be done. For me, it's kind of annoying working with stuff that I have no clue as how it works. So, I wrote this class as an experiment. Anyway, I would like some constructive criticism regarding this class.
class CODE_SYMBOL_PORT String
{
public:
String();
String(const String& String);
String(const Char* String);
//String(const Char* String, UInt32 Start, UInt32 Count);
virtual ~String();
Char *GetString() const;
const UInt32 GetLength() const;
const bool IsNull() const;
const bool IsValidIndex(const UInt32 Index) const;
UInt32 Compare(const String& String, bool IgnoreCase=false) const;
bool Find(String& Str, UInt32& Pos, bool IgnoreCase=false) const;
void Delete(UInt32 Pos, UInt32 Count);
void Insert(UInt32 Pos, Char c);
void Insert(UInt32 Pos, const String& String);
void ClipLeadingWhitespace();
void ClipTrailingWhitespace();
void Trim();
UInt32 ToInt() const;
void operator =(const String& String);
void operator =(const Char *String);
void operator +=(const String& String);
operator Char *() const;
Char& String::operator [](UInt32 Pos);
bool operator < (const String& Str) const;
bool operator > (const String& Str) const;
bool operator <=(const String& Str) const;
bool operator >=(const String& Str) const;
bool operator ==(const String& Str) const;
bool operator !=(const String& Str) const;
bool operator < (const Char *Chr) const;
bool operator > (const Char *Chr) const;
bool operator <=(const Char *Chr) const;
bool operator >=(const Char *Chr) const;
bool operator ==(const Char *Chr) const;
bool operator !=(const Char *Chr) const;
static UInt32 Length(const Char* String);
friend String CODE_SYMBOL_PORT operator +(const String& Str1, const String& Str2);
protected:
void Optimize();
void Grow(UInt32 Num);
protected:
Char *Text;
UInt32 Size;
UInt32 Len;
};
String::String()
{
Text = NULL;
Len = Size = 0;
};
String::String(const String& String)
{
Size = String.Size;
Len = String.Len;
if (Size && Len)
{
Text = new Char[Size];
_tcscpy(Text, String.Text);
}
else
{
Text = NULL;
};
};
String::String(const Char *String)
{
if (String == NULL)
{
Text = NULL;
Size = Len = 0;
return;
};
Size = Length(String) + 1;
Len = Size-1;
Text = new Char[Size];
for (UInt32 i=0 ; i<Len ; i++)
Text = (Char)String;
Text[Len] = T('\0');
};
//String::String(const Char* Str, UInt32 Start, UInt32 Count)
//{
// if (!IsValidIndex(Start) || Count <= 0)
// {
// Text = T("");
// return;
// };
// Char *Text = new Char[Count + 1];
// _tcsncpy(Text, &Str[Start], Count);
// Text[Count] = T('\0');
// return;
//};
String::~String()
{
if (Size && Text != NULL)
delete[] Text;
};
Char *String::GetString() const
{
return Text;
};
const UInt32 String::GetLength() const
{
return Len;
};
const bool String::IsNull() const
{
return (Text == NULL || !Length(Text));
};
const bool String::IsValidIndex(const UInt32 Index) const
{
return (Index >= 0 && Index < Len);
};
UInt32 String::Compare(const String& String, bool IgnoreCase) const
{
if (IsNull() && !String.IsNull())
return 1;
else if (!IsNull() && String.IsNull())
return -1;
else if (IsNull() && String.IsNull())
return 0;
/////////????????????????????//////////
if (IgnoreCase)
return _tcsicmp(Text, String.Text);
else
return _tcscmp(Text, String.Text);
};
bool String::Find(String& Str, UInt32& Pos, bool IgnoreCase) const
{
if (IsNull() || Str.IsNull())
return false;
int (* cmpfn)(const Char*, const Char*, size_t) = (IgnoreCase) ? _tcsnicmp : _tcsncmp;
for (Pos=0; Pos <= (Len-Str.Len); Pos++)
{
if(IgnoreCase)
if (_tcsnicmp(&Text[Pos], Str.Text, Str.Len) == 0)
return true;
else
if (_tcsncmp(&Text[Pos], Str.Text, Str.Len) == 0)
return true;
};
return false;
};
void String::Delete(UInt32 Pos, UInt32 Count)
{
if (Pos > Len || Count==0)
return;
if (Pos + Count > Len)
Count = (Len - Pos);
for (UInt32 i=Pos ; i<Len-Count ; i++)
Text = Text[i+Count];
Len -= Count;
Text[Len] = T('\0');
Optimize();
};
void String::Insert(UInt32 Pos, Char c)
{
if (Pos<0 || Pos>Len)
return;
Grow(1);
memmove((void *)&Text[Pos+1], (const void *)&Text[Pos], Len-Pos);
Text[Pos] = c;
Text[++Len] = T('\0');
};
void String::Insert(UInt32 Pos, const String& String)
{
if (Pos<0 || Pos>Len || String.IsNull())
return;
Char *New = new Char[String.Len + Len + 1];
if (Pos > 0)
_tcsncpy(New, Text, Pos);
_tcsncpy(&New[Pos], String.Text, String.Len);
if (Len-Pos > 0)
_tcsncpy(&New[Pos+String.Len], &Text[Pos], Len-Pos);
if (New == NULL)
{
Text = NULL;
Size = Len = 0;
return;
};
Size = Length(New) + 1;
Len = Size-1;
Text = new Char[Size];
_tcscpy(Text, New);
};
void String::ClipLeadingWhitespace()
{
if (IsNull())
return;
UInt32 i;
for (i=0 ; i<Len ; i++)
{
if (Text != 0x20 && Text != 0x09)
break;
};
Delete(0, i);
};
void String::ClipTrailingWhitespace()
{
if (IsNull())
return;
UInt32 i;
for (i=Len-1 ; i>=0 ; i--)
{
if (Text != 0x20 && Text != 0x09)
break;
};
Delete(i+1, Len-i-1);
};
void String::Trim()
{
ClipLeadingWhitespace();
ClipTrailingWhitespace();
};
UInt32 String::ToInt() const
{
if (IsNull())
return 0;
# if CODE_UNICODE == 1
return _wtoi(Text);
# else
return atoi(Text);
# endif
};
void String::operator=(const String& str)
{
Size = str.Size;
Len = str.Len;
if (Size && Len)
{
Text = new Char[Size];
_tcscpy(Text, str.Text);
}
else
{
Text = NULL;
};
};
void String::operator=(const Char *str)
{
Len = Length(str);
Size = Len + 1;
if (Size && Len)
{
Text = new Char[Size];
_tcscpy(Text, str);
}
else
{
Text = NULL;
};
};
void String::operator +=(const String& String)
{
if (String.Len > 0)
{
Grow(String.Len);
_tcsncpy(&Text[Len], String.Text, String.Len);
Len += String.Len;
};
};
String::operator Char *() const
{
return Text;
};
Char& String::operator [](UInt32 Pos)
{
if (Pos < 0)
return Text[0];
else if (Pos >= Len)
{
Grow(Pos+2);
return Text[Pos];
}
else
return Text[Pos];
};
bool String::operator < (const String& Str) const { return (bool)(Compare(Str) == -1); };
bool String::operator > (const String& Str) const { return (bool)(Compare(Str) == 1); };
bool String::operator <=(const String& Str) const { return (bool)(Compare(Str) != 1); };
bool String::operator >=(const String& Str) const { return (bool)(Compare(Str) != -1); };
bool String::operator ==(const String& Str) const { return (bool)(Compare(Str) == 0); };
bool String::operator !=(const String& Str) const { return (bool)(Compare(Str) != 0); };
bool String::operator < (const Char *Chr) const { return (bool)(Compare(String(Chr)) == -1); };
bool String::operator > (const Char *Chr) const { return (bool)(Compare(String(Chr)) == 1); };
bool String::operator <=(const Char *Chr) const { return (bool)(Compare(String(Chr)) != 1); };
bool String::operator >=(const Char *Chr) const { return (bool)(Compare(String(Chr)) != -1); };
bool String::operator ==(const Char *Chr) const { return (bool)(Compare(String(Chr)) == 0); };
bool String::operator !=(const Char *Chr) const { return (bool)(Compare(String(Chr)) != 0); };
void String::Optimize()
{
Size = Len + 1;
Char *Temp = new Char[Size];
_tcscpy(Temp, Text);
delete[] Text;
Text = Temp;
};
void String::Grow(UInt32 Num)
{
Size += Num;
Char *Temp = new Char[Size];
_tcscpy(Temp, Text);
delete[] Text;
Text = Temp;
};
UInt32 String::Length(const Char* String)
{
UInt32 Length = 0;
while(*String++)
++Length;
return Length;
};
String operator +(const String& Str1, const String& Str2)
{
Char *Temp = new Char[Str1.Size + Str2.Size];
if (Str1.Len)
_tcscpy(Temp, Str1.Text);
if (Str2.Len)
_tcscpy(&Temp[Str1.Len], Str2.Text);
String Result = Temp;
return Result;
};
Thanks for any thoughts[smile],
Chad Seibert
[Edited by - Chad Seibert on April 6, 2007 3:07:05 PM]