📄 string.cpp
字号:
// Module: String (Dynamic Strings)
// Version: 2.01 26-Oct-1989
//
// Language: C++ 2.0
// Environ: Any
// Compilers: Zortech C++ 2.01
//
// Purpose: Provides a general dynamic string class.
//
// Written by: Scott Robert Ladd
// 705 West Virginia
// Gunnison CO 81230
//
// MCI ID: srl
// FidoNet: 1:104/708
#include "string.hpp"
#include "stream.hpp"
#include "string.h"
#include "stddef.h"
#include "stdlib.h"
#include "ctype.h"
#include "limits.h"
static void DefaultHandler(StrError Err);
// class-global constant intialization
unsigned int String::AllocIncr = 16;
void (*String::ErrorHandler)(StrError) = DefaultHandler;
// default exception handler
static void DefaultHandler(StrError Err)
{
cout << "\aERROR in String object: ";
switch (Err)
{
case SE_ALLOC :
cout << "memory allocation failure";
break;
case SE_TOO_LONG :
cout << "exceeded " << UINT_MAX << " character limit";
}
cout << "\n";
exit(1);
}
// private function to shrink the size of an allocated string
void String::Shrink()
{
char * Temp;
if ((Siz - Len) > AllocIncr)
{
Siz = ((Len + AllocIncr - 1) / AllocIncr) * AllocIncr;
Temp = new char[Siz];
if (Temp != NULL)
{
memcpy(Temp,Txt,Len);
delete Txt;
Txt = Temp;
}
else
ErrorHandler(SE_ALLOC);
}
}
// constructor
String::String()
{
Len = 0;
Siz = AllocIncr;
Txt = new char[Siz];
if (Txt == NULL)
ErrorHandler(SE_ALLOC);
Txt[0] = '\x00';
}
String::String(const String & Str)
{
Len = Str.Len;
Siz = Str.Siz;
Txt = new char[Siz];
if (Txt == NULL)
ErrorHandler(SE_ALLOC);
memcpy(Txt,Str.Txt,Len);
}
String::String(char * Cstr)
{
Len = strlen(Cstr);
Siz = ((Len + AllocIncr - 1) / AllocIncr) * AllocIncr;
Txt = new char[Siz];
if (Txt == NULL)
ErrorHandler(SE_ALLOC);
memcpy(Txt,Cstr,Len);
}
String::String(char FillCh, unsigned int Count)
{
unsigned int Pos;
Siz = ((Count + AllocIncr - 1) / AllocIncr) * AllocIncr;
Len = Siz;
Txt = new char[Siz];
if (Txt == NULL)
ErrorHandler(SE_ALLOC);
memset(Txt,FillCh,Count);
}
// destructor
String::~String()
{
delete Txt;
}
// value return methods
unsigned int String::Length()
{
return Len;
}
unsigned int String::Size()
{
return Siz;
}
// Assign an exception handler
void String::SetErrorHandler(void (* UserHandler)(StrError))
{
ErrorHandler = UserHandler;
}
// Function to return a blank string
String Empty()
{
static String EmptyStr;
return EmptyStr;
}
// copy String to c-string method
void String::Copy(char * Cstr, unsigned int Max)
{
unsigned int CopyLen;
if (Max == 0)
return;
if (Len >= Max)
CopyLen = Max - 1;
else
CopyLen = Len;
memcpy(Cstr,Txt,CopyLen);
Cstr[CopyLen] = '\x00';
}
// create a c-string from String method
char * String::Dupe()
{
char * new_cstr;
new_cstr = new char[Len + 1];
memcpy(new_cstr,Txt,Len);
new_cstr[Len] = '\x00';
return new_cstr;
}
// assignment method
void String::operator = (const String & Str)
{
Len = Str.Len;
Siz = Str.Siz;
delete Txt;
Txt = new char[Siz];
if (Txt == NULL)
ErrorHandler(SE_ALLOC);
memcpy(Txt,Str.Txt,Len);
}
// concatenation methods
String operator + (const String & Str1, const String & Str2)
{
unsigned long TotalLen;
unsigned int NewLen, NewSiz, CopyLen;
String TempStr;
char * Temp;
TotalLen = Str1.Len + Str2.Len;
if (TotalLen > UINT_MAX)
(*String::ErrorHandler)(SE_TOO_LONG);
TempStr = Str1;
CopyLen = Str2.Len;
NewLen = TempStr.Len + Str2.Len;
NewSiz = TempStr.Siz + Str2.Siz;
Temp = new char[NewSiz];
if (Temp == NULL)
(*String::ErrorHandler)(SE_ALLOC);
memcpy(Temp,TempStr.Txt,TempStr.Len);
delete TempStr.Txt;
TempStr.Txt = Temp;
memcpy(&TempStr.Txt[TempStr.Len],Str2.Txt,CopyLen);
TempStr.Len = NewLen;
TempStr.Siz = NewSiz;
TempStr.Shrink();
return TempStr;
}
void String::operator += (const String & Str)
{
unsigned long TotalLen;
unsigned int NewLen, NewSiz, CopyLen;
char * Temp;
TotalLen = Str.Len + Len;
if (TotalLen > UINT_MAX)
ErrorHandler(SE_TOO_LONG);
CopyLen = Str.Len;
NewLen = unsigned int (TotalLen);
NewSiz = Siz + Str.Siz;
Temp = new char[NewSiz];
if (Temp == NULL)
ErrorHandler(SE_ALLOC);
memcpy(Temp,Txt,Len);
delete Txt;
Txt = Temp;
memcpy(&Txt[Len],Str.Txt,CopyLen);
Len = NewLen;
Siz = NewSiz;
Shrink();
}
// comparison methods
int String::operator < (const String & Str)
{
return (Compare(Str) == SC_LESS);
}
int String::operator > (const String & Str)
{
return (Compare(Str) == SC_GREATER);
}
int String::operator <= (const String & Str)
{
return (Compare(Str) != SC_GREATER);
}
int String::operator >= (const String & Str)
{
return (Compare(Str) != SC_LESS);
}
int String::operator == (const String & Str)
{
return (Compare(Str) == SC_EQUAL);
}
int String::operator != (const String & Str)
{
return (Compare(Str) != SC_EQUAL);
}
StrCompVal String::Compare(const String & Str, StrCompMode Case)
{
unsigned int Index, MaxIndex;
char Ch1, Ch2;
if (Len == 0)
if (Str.Len == 0)
return SC_EQUAL;
else
return SC_LESS;
else
if (Str.Len == 0)
return SC_GREATER;
MaxIndex = Len > Str.Len ? Len : Str.Len;
Index = 0;
if (Case == SM_IGNORE)
{
do {
Ch1 = toupper(Txt[Index]);
Ch2 = toupper(Str.Txt[Index]);
if (Ch1 == Ch2)
++Index;
else
if (Txt[Index] < Str.Txt[Index])
return SC_LESS;
else
return SC_GREATER;
}
while (Index < MaxIndex);
}
else
{
do {
Ch1 = Txt[Index];
Ch2 = Str.Txt[Index];
if (Ch1 == Ch2)
++Index;
else
if (Txt[Index] < Str.Txt[Index])
return SC_LESS;
else
return SC_GREATER;
}
while (Index < MaxIndex);
}
return SC_EQUAL;
}
// substring search methods
int String::Find(const String & Str, unsigned int & Pos, StrCompMode Case)
{
char * TempStr1, * TempStr2;
unsigned int LastPos, SearchLen, TempPos;
int Found;
TempStr1 = new char[Len + 1];
if (TempStr1 == NULL)
ErrorHandler(SE_ALLOC);
memcpy(TempStr1,Txt,Len);
TempStr1[Len] = '\x00';
TempStr2 = new char[Str.Len + 1];
if (TempStr2 == NULL)
ErrorHandler(SE_ALLOC);
memcpy(TempStr2,Str.Txt,Str.Len);
TempStr2[Str.Len] = '\x00';
if (Case == SM_IGNORE)
{
strupr(TempStr1);
strupr(TempStr2);
}
Pos = 0;
TempPos = 0;
Found = 0;
SearchLen = Str.Len;
LastPos = Len - SearchLen;
while ((TempPos <= LastPos) && !Found)
{
if (0 == strncmp(&TempStr1[TempPos],TempStr2,SearchLen))
{
Pos = TempPos;
Found = 1;
}
else
++TempPos;
}
delete TempStr1;
delete TempStr2;
return Found;
}
// substring deletion method
void String::Delete(unsigned int Pos, unsigned int Count)
{
unsigned int CopyPos;
if (Pos > Len)
return;
CopyPos = Pos + Count;
if (CopyPos >= Len)
Txt[Pos] = 0;
else
while (CopyPos <= Len)
{
Txt[Pos] = Txt[CopyPos];
++Pos;
++CopyPos;
}
Len -= Count;
Shrink();
}
// substring insertion methods
void String::Insert(unsigned int Pos, char Ch)
{
char * Temp;
if (Pos > Len)
return;
if (Len == Siz)
{
Siz += AllocIncr;
Temp = new char[Siz];
if (Temp == NULL)
ErrorHandler(SE_ALLOC);
memcpy(Temp,Txt,Len);
delete Txt;
Txt = Temp;
}
if (Pos < Len)
for (unsigned int Col = Len + 1; Col > Pos; --Col)
Txt[Col] = Txt[Col-1];
Txt[Pos] = Ch;
++Len;
}
void String::Insert(unsigned int Pos, const String & Str)
{
unsigned long TotalLen = Str.Len + Len;
if (TotalLen > UINT_MAX)
ErrorHandler(SE_TOO_LONG);
unsigned int SLen = Str.Len;
if (SLen > 0)
for (unsigned int I = 0; I < SLen; ++I)
{
Insert(Pos,Str.Txt[I]);
++Pos;
}
}
// substring retrieval method
String String::SubStr(unsigned int Start, unsigned int Count)
{
String TempStr;
char * Temp;
if ((Start < Len) && (Count > 0))
for (unsigned int Pos = 0; Pos < Count; ++Pos)
{
if (TempStr.Len == TempStr.Siz)
{
TempStr.Siz += AllocIncr;
Temp = new char[TempStr.Siz];
if (Temp == NULL)
ErrorHandler(SE_ALLOC);
memcpy(Temp,TempStr.Txt,Len);
delete TempStr.Txt;
TempStr.Txt = Temp;
}
TempStr.Txt[Pos] = Txt[Start + Pos];
++TempStr.Len;
}
return TempStr;
}
// character retrieval method
char String::operator [] (unsigned int Pos)
{
if (Pos >= Len)
return '\x00';
return Txt[Pos];
}
// case-modification methods
String String::ToUpper()
{
String TempStr = *this;
for (unsigned int Pos = 0; Pos < Len; ++Pos)
TempStr.Txt[Pos] = toupper(TempStr.Txt[Pos]);
return TempStr;
}
String String::ToLower()
{
String TempStr = *this;
for (unsigned int Pos = 0; Pos < Len; ++Pos)
TempStr.Txt[Pos] = tolower(TempStr.Txt[Pos]);
return TempStr;
}
// stream I/O methods
istream & operator >> (istream & Input, const String & Str)
{
char Buffer[256];
Input >> Buffer;
Str = Buffer;
return Input;
}
ostream & operator << (ostream & Output, const String & Str)
{
unsigned int Index;
for (Index = 0; Index < Str.Len; ++Index)
Output << form("%c",Str.Txt[Index]);
return Output;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -