home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Supreme Volume 6 #1
/
swsii.zip
/
swsii
/
099
/
STRPP300.ZIP
/
STR.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-11
|
18KB
|
908 lines
/* -------------------------------------------------------------------- */
/* String++ Version 3.00 04/10/93 */
/* */
/* Enhanced string class for Turbo C++/Borland C++. */
/* Copyright 1991-1993 by Carl W. Moreland */
/* */
/* str.cpp */
/* -------------------------------------------------------------------- */
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef BCCL
#include "strng.h"
#else
#include "str.h"
#endif
const String STR_NULL = "";
const String& Str = STR_NULL;
const String& StrNull = STR_NULL;
unsigned String::strMinLength = 16;
unsigned String::strIncLength = 8;
String* String::findIn = 0;
String& String::findStr = (String&)StrNull;
unsigned String::findPos = 0;
String String::fpFormat("%0.4f");
/* ----- Constructors/Destructors ------------------------------------- */
String::String()
{
strPtr = 0;
strLen = 0;
bufferLen = 0;
}
String::String(const char c, const unsigned n)
{
strPtr = 0;
strLen = 0;
bufferLen = 0;
SetStr(c, n);
}
String::String(const char* p)
{
strPtr = 0;
strLen = 0;
bufferLen = 0;
SetStr(p);
}
String::String(const char* p, const unsigned pos, const unsigned len)
{
strPtr = 0;
strLen = 0;
bufferLen = 0;
SetStr(p, pos, len);
}
String::String(const String& s)
{
strPtr = 0;
strLen = 0;
bufferLen = 0;
SetStr(s);
}
String::String(const String& s, const unsigned pos, const unsigned len)
{
strPtr = 0;
strLen = 0;
bufferLen = 0;
SetStr(s, pos, len);
}
String::String(const int n)
{
strPtr = 0;
strLen = 0;
bufferLen = 0;
ltos((long)n);
}
String::String(const long n)
{
strPtr = 0;
strLen = 0;
bufferLen = 0;
ltos(n);
}
String::String(const float n, const char* format)
{
strPtr = 0;
strLen = 0;
bufferLen = 0;
dtos((double)n, format);
}
String::String(const double n, const char* format)
{
strPtr = 0;
strLen = 0;
bufferLen = 0;
dtos(n, format);
}
String::~String(void)
{
if(strPtr)
delete strPtr;
}
/* ----- SetStr/AddStr ------------------------------------------------ */
void String::SetStr(const char c, const unsigned n)
{
int i;
strLen = n;
if(bufferLen > strLen) // if the buffer is large enough...
{
for(i=0; i<strLen; i++)
strPtr[i] = c; // copy n chars
}
else // else create a new buffer
{
if(strPtr)
delete strPtr;
strPtr = new char[GetSize(strLen)]; // allocate the memory
for(i=0; i<strLen; i++)
strPtr[i] = c; // copy n chars
}
strPtr[strLen] = 0; // add NULL termination
}
void String::SetStr(const char* p)
{
strLen = strlen(p);
if(bufferLen > strLen) // if the buffer is large enough...
memcpy(strPtr, p, strLen); // copy the String
else // else create a new buffer
{
char* tmp = new char[GetSize(strLen)];
memcpy(tmp, p, strLen); // copy the String
if(strPtr)
delete strPtr;
strPtr = tmp; // now make strPtr = tmp
}
strPtr[strLen] = 0; // add NULL termination
}
void String::SetStr(const char* p, const unsigned pos, const unsigned len)
{
int p_len = strlen(p);
if(pos > p_len) // error check the start pos
return;
strLen = p_len - pos;
if(len < strLen) // error check the copy length
strLen = len;
if(bufferLen > strLen) // if the buffer is large enough...
memcpy(strPtr, p+pos, strLen); // copy the substring
else // else create a new buffer
{
char* tmp = new char[GetSize(strLen)];
memcpy(tmp, p+pos, strLen); // copy the substring
if(strPtr)
delete strPtr;
strPtr = tmp; // now make strPtr = tmp
}
strPtr[strLen] = 0; // add NULL termination
}
void String::SetStr(const String& s)
{
strLen = s.strLen;
if(bufferLen > strLen) // if the buffer is large enough...
memcpy(strPtr, s.strPtr, strLen); // copy the String
else // else create a new buffer
{
char* tmp = new char[GetSize(strLen)];
memcpy(tmp, s.strPtr, strLen); // copy the String
if(strPtr)
delete strPtr;
strPtr = tmp; // now make strPtr = tmp
}
strPtr[strLen] = 0; // add NULL termination
}
void String::SetStr(const String& s, const unsigned pos, const unsigned len)
{
if(pos > s.strLen) // error check the start pos
return;
strLen = s.strLen - pos;
if(len < strLen) // error check the copy length
strLen = len;
if(bufferLen > strLen) // if the buffer is large enough...
memcpy(strPtr, s.strPtr+pos, strLen); // copy the substring
else // else create a new buffer
{
char* tmp = new char[GetSize(len)]; // allocate new memory
memcpy(tmp, s.strPtr+pos, len); // copy the subString
if(strPtr)
delete strPtr;
strPtr = tmp; // now make strPtr = tmp
}
strPtr[strLen] = 0; // add NULL termination
}
void String::AddStr(const char c)
{
strLen += 1;
if(bufferLen > strLen) // if the buffer is large enough...
strPtr[strLen-1] = c; // append character c
else // else create a new buffer
{
char* tmp = new char[GetSize(strLen)];
memcpy(tmp, strPtr, strLen-1); // copy the original String
tmp[strLen-1] = c; // append character c
if(strPtr)
delete strPtr;
strPtr = tmp; // now make strPtr = tmp
}
strPtr[strLen] = 0; // add NULL termination
}
void String::AddStr(const char* p)
{
unsigned s_len = strlen(p);
if(bufferLen > strLen+s_len) // if the buffer is large enough...
memcpy(strPtr+strLen, p, s_len); // append String p
else // else create a new buffer
{
char* tmp = new char[GetSize(strLen+s_len)];
memcpy(tmp, strPtr, strLen); // copy the original String
memcpy(tmp+strLen, p, s_len); // append String p
if(strPtr)
delete strPtr;
strPtr = tmp; // now make strPtr = tmp
}
strLen += s_len;
strPtr[strLen] = 0; // add NULL termination
}
void String::AddStr(const String& s)
{
if(bufferLen > strLen + s.strLen) // if the buffer is large enough...
memcpy(strPtr+strLen, s.strPtr, s.strLen); // append String s
else // else create a new buffer
{
char* tmp = new char[GetSize(strLen+s.strLen)];
memcpy(tmp, strPtr, strLen); // copy the original String
memcpy(tmp+strLen, s.strPtr, s.strLen); // append String s
if(strPtr)
delete strPtr;
strPtr = tmp; // now make strPtr = tmp
}
strLen += s.strLen;
strPtr[strLen] = 0; // add NULL termination
}
void String::ltos(const long n)
{
char num[15];
ltoa(n, num, 10);
SetStr(num);
}
void String::dtos(const double n, const char* format)
{
char num[40];
if(format[0] != 0 && fpFormat != format)
fpFormat = format;
sprintf(num, fpFormat, n);
SetStr(num);
}
unsigned String::GetSize(unsigned n)
{
bufferLen = strMinLength; // start with strMinLength
if(n > bufferLen)
{
while(n > bufferLen)
bufferLen += strIncLength; // incrementally add strIncLength
}
bufferLen++; // add one for NULL termination
return bufferLen;
}
unsigned String::SetSize(unsigned len)
{
if(len < strLen)
return 0;
bufferLen = len + 1;
char *tmp = new char[bufferLen];
memcpy(tmp, strPtr, strLen); // copy the original String
tmp[strLen] = 0; // add NULL termination
if(strPtr) // now make strPtr = tmp
delete strPtr;
strPtr = tmp;
return bufferLen-1;
}
void String::Minimize(void)
{
if(strLen < bufferLen-1)
SetSize(strLen);
}
void String::SetFloatFormat(const char* format) const
{
if(format[0] != 0)
fpFormat = format;
}
/* -------------------------------------------------------------------- */
String& String::Right(unsigned len)
{
SetStr(strPtr, strLen-len, len);
return *this;
}
String& String::Left(unsigned len)
{
SetStr(strPtr, 0, len);
return *this;
}
String& String::Mid(unsigned pos, unsigned len)
{
SetStr(strPtr, pos, len);
return *this;
}
String& String::Justify(char type, unsigned len, char mode)
{
if(mode&TRIM)
Trim(); // delete outter whitespace
if(strLen >= len && !(mode&CLIP)) // check for out-of-bounds
return *this;
if(strLen > len && (mode&CLIP)) // check for clipping
{
if(type == LEFT)
Left(len);
else if(type == CENTER)
Mid((strLen-len)/2, len);
else if(type == RIGHT)
Right(len);
return *this; // return clipped String
}
if(type == LEFT)
*this = *this + String(' ', len-strLen);
else if(type == CENTER)
*this = String(' ', (len-strLen)/2) + *this +
String(' ', len - (len+strLen)/2);
else if(type == RIGHT)
*this = String(' ', len-strLen) + *this;
strLen = strlen(strPtr);
return *this; // return normal String
}
String& String::toUpper(void)
{
for(int i=0; i<strlen(strPtr); i++)
strPtr[i] = ::toupper(strPtr[i]);
return *this;
}
String& String::toLower(void)
{
for(int i=0; i<strlen(strPtr); i++)
strPtr[i] = ::tolower(strPtr[i]);
return *this;
}
int& String::Value(int& n) const
{
n = atoi(strPtr);
return n;
}
long& String::Value(long& n) const
{
n = atol(strPtr);
return n;
}
float& String::Value(float& n) const
{
n = (float)atof(strPtr);
return n;
}
double& String::Value(double& n) const
{
n = atof(strPtr);
return n;
}
String& String::Insert(unsigned pos, const String& s)
{
if(pos > strLen)
return *this;
if(bufferLen > strLen + s.strLen)
{
memmove(strPtr+pos+s.strLen, strPtr+pos, strLen-pos);
memcpy(strPtr+pos, s.strPtr, s.strLen);
}
else
{
GetSize(strLen + s.strLen);
char* tmp = new char[bufferLen];
memcpy(tmp, strPtr, pos);
memcpy(tmp+pos, s.strPtr, s.strLen);
memcpy(tmp+pos+s.strLen, strPtr+pos, strLen-pos);
delete strPtr;
strPtr = tmp;
}
strLen += s.strLen;
strPtr[strLen] = 0;
return *this;
}
String& String::Delete(unsigned pos, unsigned len)
{
if(pos >= strLen)
return *this;
if(len > strLen - pos)
len = strLen - pos;
if(len == 0)
len = strLen - pos;
strLen -= len;
memmove(strPtr+pos, strPtr+pos+len, strLen-pos);
strPtr[strLen] = 0;
return *this;
}
String& String::Replace(unsigned pos, unsigned len, const String& to)
{
Delete(pos, len);
Insert(pos, to);
return *this;
}
char* String::Copy(char*& p) const
{
p = new char[strLen + 1];
memcpy(p, strPtr, strLen);
return p;
}
String& String::Trim(int mode, char c)
{
int begin = 0;
int end = strLen-1;
if(c == WHITESPACE) // if we're deleting whitespaces...
{
if(mode == LEFT || mode == CENTER) // delete leading whitespace
{
while(isspace(strPtr[begin]) && begin <= end)
begin++;
}
if(mode == RIGHT || mode == CENTER) // delete trailing whitespace
{
while(isspace(strPtr[end]) && end >= begin)
end--;
}
}
else // else a character was specified
{
if(mode == LEFT || mode == CENTER) // delete leading characters
{
while(strPtr[begin] == c && begin <= end)
begin++;
}
if(mode == RIGHT || mode == CENTER) // delete trailing characters
{
while(strPtr[end] == c && end >= begin)
end--;
}
}
SetStr(strPtr, begin, end-begin+1);
return *this;
}
/* ----- Find methods ------------------------------------------------- */
int String::FindFirst(const String& s) const
{
char* tmp;
if((tmp = strstr(strPtr, s.strPtr)) != NULL)
{
findIn = (String*)this;
findStr = s;
findPos = (int)(tmp-strPtr);
}
else
{
findStr = 0;
findPos = -1;
}
return findPos;
}
int String::FindNext(void) const
{
char* tmp;
if(findIn != this) // wrong string
return -1;
if((tmp = strstr(strPtr+findPos+1, findStr.strPtr)) != NULL)
findPos += (int)(tmp-(strPtr+findPos));
else
{
findStr = 0;
findPos = -1;
}
return findPos;
}
int String::FindPrev(void) const
{
if(findIn != this) // wrong string
return -1;
for(int i = findPos-findStr.strLen; i >= 0; i--)
{
if(memcmp(strPtr+i, findStr.strPtr, findStr.strLen) == 0)
{
findPos = i;
return findPos;
}
}
findPos = -1;
return findPos;
}
int String::FindLast(const String& s) const
{
for(int i = strLen-s.strLen; i > 0; i--)
{
if(memcmp(strPtr+i, s.strPtr, s.strLen) == 0)
{
findIn = (String*)this;
findStr = s;
findPos = i;
return findPos;
}
}
findIn = 0;
findPos = -1;
return findPos;
}
/* ----- Operators ---------------------------------------------------- */
String String::operator()(unsigned pos, unsigned len) const
{
String tmp(strPtr, pos, len);
return tmp;
}
String& String::operator=(const char c)
{
SetStr(c);
return *this;
}
String& String::operator=(const char* p)
{
SetStr(p);
return *this;
}
String& String::operator=(const String& s)
{
SetStr(s);
return *this;
}
String& String::operator=(const long n)
{
ltos(n);
return *this;
}
String& String::operator=(const double n)
{
dtos(n, "");
return *this;
}
String& String::operator+=(const char c)
{
AddStr(c);
return *this;
}
String& String::operator+=(const char* p)
{
AddStr(p);
return *this;
}
String& String::operator+=(const String& s)
{
AddStr(s);
return *this;
}
String operator+(const String& s, const char* p)
{
String tmp(s);
tmp.AddStr(p);
return tmp;
}
String operator+(const char* p, const String& s)
{
String tmp(p);
tmp.AddStr(s);
return tmp;
}
String operator+(const String& s1, const String& s2)
{
String tmp(s1);
tmp.AddStr(s2);
return tmp;
}
String operator*(const String& s1, const unsigned n)
{
String tmp(s1);
for(int i=1; i<n; i++)
tmp += s1;
return tmp;
}
String operator*(const unsigned n, const String& s1)
{
String tmp(s1);
for(int i=1; i<n; i++)
tmp += s1;
return tmp;
}
String& String::operator*=(const unsigned n)
{
unsigned nlen = n*strLen;
if(bufferLen > nlen)
{
for(int i=0; i<n; i++)
memcpy(strPtr+i*strLen, strPtr, strLen);
strPtr[nlen] = 0;
}
else
{
char *tmp = new char[nlen + 1];
for(int i=0; i<n; i++)
memcpy(tmp+i*strLen, strPtr, strLen);
tmp[nlen] = 0;
SetStr(tmp);
}
return *this;
}
char& String::operator[](const unsigned n) const
{
if(n > strLen)
return *(strPtr + strLen);
return *(strPtr + n);
}
String& String::operator<<(const char c)
{
AddStr(c);
return *this;
}
String& String::operator<<(const char* p)
{
AddStr(p);
return *this;
}
String& String::operator<<(const String& s)
{
AddStr(s);
return *this;
}
String& String::operator<<(const long n)
{
char num[15];
ltoa(n, num, 10);
AddStr(num);
return *this;
};
String& String::operator<<(const double n)
{
String tmp(n);
AddStr(tmp);
return *this;
};
/* -------------------------------------------------------------------- */
/* AWK-style functions */
/* -------------------------------------------------------------------- */
int index(const String& s, const String& t)
{
int pos;
char *tmp;
if((tmp = strstr(s, t)) != NULL)
pos = (int)(tmp-(const)s());
else
pos = -1;
return pos;
}
String substr(const String& s, unsigned pos, unsigned len)
{
String tmp(s, pos, len);
return tmp;
}
int split(const String& s, String*& array, const String& fs)
{
int i=0, j=1, start=0;
String *tmp;
while(i < s.Len()) // find the number of substrings
{
if(memcmp(s(i), fs(), fs.Len()) == 0)
j++;
i++;
}
tmp = new String[j]; // allocate the array of strings
i = 0;
j = 0;
while(i < s.Len()) // fill in the array
{
if(memcmp(s(i), fs(), fs.Len()) == 0)
{
tmp[j++] = mid(s, start, i-start);
i += fs.Len();
start = i;
}
else
i++;
}
tmp[j++] = mid(s, start, i-start);
array = tmp;
return j;
}
int gsub(const String& from, const String& to, String& s, unsigned count)
{
int i=0, j=0;
while(i <= s.Len() - from.Len())
{
if(memcmp(s(i), from(), from.Len()) == 0)
{
s = left(s, i) + to + right(s, s.Len()-i-from.Len());
i += to.Len();
if(++j == count)
break;
}
else
i++;
}
return j;
}
/* -------------------------------------------------------------------- */
/* C-style functions */
/* -------------------------------------------------------------------- */
String toupper(const String& s)
{
String tmp(s);
tmp.toUpper();
return tmp;
}
String tolower(const String& s)
{
String tmp(s);
tmp.toLower();
return tmp;
}
String left(const String& s, unsigned len)
{
String tmp(s, 0, len);
return tmp;
}
String right(const String& s, unsigned len)
{
String tmp(s, s.Len()-len, len);
return tmp;
}
String mid(const String& s, unsigned pos, unsigned len)
{
String tmp(s, pos, len);
return tmp;
}
String justify(const String& s, char type, unsigned len, char mode)
{
String tmp(s);
tmp.Justify(type, len, mode);
return tmp;
}
String trim(const String& s, int mode)
{
String tmp(s);
tmp.Trim(mode);
return tmp;
}
/* ----- Stream I/O --------------------------------------------------- */
ostream& operator<<(ostream& strm, const String& s)
{
return strm << s();
}
istream& operator>>(istream& strm, String& s)
{
char p[256];
strm >> p;
s = p;
return strm;
}