⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 string.cpp

📁 C++中的字符串类的程序
💻 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 + -