2026-10-04 00:04:20 +08:00
|
|
|
|
//----------------------------------------------------------------------------- +
|
2026-09-28 15:28:50 +08:00
|
|
|
|
// Copyright (C), 1998-2007, SH Software Co. Ltd.
|
|
|
|
|
|
// = FileName : AString.cpp
|
|
|
|
|
|
// = Version : ver2.0
|
|
|
|
|
|
// = Author : zjq
|
|
|
|
|
|
// = CreateDate : 2002-09-09
|
2026-10-04 00:04:20 +08:00
|
|
|
|
// = Description: 类的定义
|
2026-09-28 15:28:50 +08:00
|
|
|
|
// = Maintainers:
|
|
|
|
|
|
//
|
|
|
|
|
|
//----------------------------------------------------------------------------- +
|
|
|
|
|
|
#include "StdAfx.h"
|
|
|
|
|
|
#include "AString.h"
|
|
|
|
|
|
#include "ListQuene.h"
|
|
|
|
|
|
#include "WValList.h"
|
|
|
|
|
|
|
|
|
|
|
|
AString::AString(const wchar_t *sw)
|
|
|
|
|
|
: Array<char> (1)
|
|
|
|
|
|
{
|
|
|
|
|
|
Clear();
|
|
|
|
|
|
if(sw == NULL)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
USES_CONVERSION;
|
|
|
|
|
|
*this = W2A(sw);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AString::~AString()
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AString::Copy(const char *p,long pos)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(p == NULL)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
long size(0);
|
|
|
|
|
|
for(size = 0; p[size] != NULL; size++);
|
|
|
|
|
|
|
|
|
|
|
|
long length1 = pos + size;
|
|
|
|
|
|
|
|
|
|
|
|
if(length1 > Length())
|
|
|
|
|
|
{
|
|
|
|
|
|
SetLength(length1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
memcpy(pData + pos,p,size*sizeof(char));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AString::Copy(long from,long to,long size)
|
|
|
|
|
|
{
|
|
|
|
|
|
long length1 = to + size;
|
|
|
|
|
|
if(length1 > Length())
|
|
|
|
|
|
{
|
|
|
|
|
|
SetLength(length1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
char *p1 = pData + from, *p2 = pData + to;
|
|
|
|
|
|
if(from > to)
|
|
|
|
|
|
{
|
|
|
|
|
|
for(long i = 0; i < size; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
p2[i] = p1[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(to > from)
|
|
|
|
|
|
{
|
|
|
|
|
|
for(long i = size - 1; i >= 0; i--)
|
|
|
|
|
|
{
|
|
|
|
|
|
p2[i] = p1[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AString::MakeUpper()
|
|
|
|
|
|
{
|
|
|
|
|
|
for(long i = 0; i < Length();i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
char &c = (*this)[i];
|
|
|
|
|
|
if(c >= 'a' && c <= 'z')
|
|
|
|
|
|
{
|
|
|
|
|
|
c -= 32;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AString& AString::operator << (double d)
|
|
|
|
|
|
{
|
|
|
|
|
|
AString s;
|
|
|
|
|
|
s.Format("%f",d);
|
|
|
|
|
|
|
|
|
|
|
|
Copy(s,m_nEnd);
|
|
|
|
|
|
|
|
|
|
|
|
long i = m_nEnd - 1;
|
|
|
|
|
|
|
|
|
|
|
|
while(pData[i] == '0' && pData[i-1] != '.')
|
|
|
|
|
|
{
|
|
|
|
|
|
i--;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SetEnd(i + 1);
|
|
|
|
|
|
return *this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AString& AString::Format(const char*format,...)
|
|
|
|
|
|
{
|
|
|
|
|
|
Clear();
|
|
|
|
|
|
|
|
|
|
|
|
Realloc(1024,false);
|
|
|
|
|
|
va_list vlist;
|
|
|
|
|
|
va_start(vlist, format);
|
|
|
|
|
|
vsprintf(pData, format, vlist);
|
|
|
|
|
|
va_end(vlist);
|
|
|
|
|
|
m_nEnd = strlen(pData);
|
|
|
|
|
|
return *this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AString& AString::Extract(const char*format,...)
|
|
|
|
|
|
{
|
|
|
|
|
|
WValList vList(format,*this);
|
|
|
|
|
|
|
|
|
|
|
|
char*curP = (char*)(&format) + sizeof(char*);
|
|
|
|
|
|
|
|
|
|
|
|
for(vList.MoveToFirst(); !vList.IsOut(); vList.MoveToNext())
|
|
|
|
|
|
{
|
|
|
|
|
|
WFormatUnit*p = vList.GetCurData();
|
|
|
|
|
|
switch(p->type)
|
|
|
|
|
|
{
|
|
|
|
|
|
case WS_CHAR:
|
|
|
|
|
|
**((char**)curP) = p->GetAt(0);
|
|
|
|
|
|
curP += sizeof(char**);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case WS_INT:
|
|
|
|
|
|
*p >> **((int**)curP);
|
|
|
|
|
|
curP += sizeof(int**);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case WS_DOUBLE:
|
|
|
|
|
|
*p >> **((double**)curP);
|
|
|
|
|
|
curP += sizeof(double**);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case WS_STRING:
|
|
|
|
|
|
*p >> **((AString**)curP);
|
|
|
|
|
|
curP += sizeof(AString**);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return *this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
long AString::ReverseFind(char c) const
|
|
|
|
|
|
{
|
|
|
|
|
|
for(long i = m_nEnd - 1; i >= 0; i--)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(pData[i] == c)
|
|
|
|
|
|
{
|
|
|
|
|
|
return i;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return NOT_FOUND;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
long AString::Find(const AString& s, long from, long to) const
|
|
|
|
|
|
{
|
|
|
|
|
|
if(s.IsEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
return NOT_FOUND;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(to == -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
to = Length() - 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
long *next = new long[s.Length()];
|
|
|
|
|
|
s.CreateNextTable(next);
|
|
|
|
|
|
long i(from), j(0);
|
|
|
|
|
|
for(i = from, j = 0; i <= to && j < s.Length();)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(pData[i] == s[j])
|
|
|
|
|
|
{
|
|
|
|
|
|
i++;
|
|
|
|
|
|
j++;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
j = next[j];
|
|
|
|
|
|
if(j == -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
j = 0;
|
|
|
|
|
|
i++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
delete[] next;
|
|
|
|
|
|
if(j == s.Length())
|
|
|
|
|
|
{
|
|
|
|
|
|
return i - j;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return NOT_FOUND;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-10-04 00:04:20 +08:00
|
|
|
|
//next(i)=j 当j>0,j为使得p(0)...p(j-1) == p(i-j)...p(i-1)的最大整数;
|
|
|
|
|
|
//当j>=0,表示当前被比较字符与当前索引为i的比较字符不相同时,当前比较字符移到j处继续比较;
|
|
|
|
|
|
//当j=-1,表示当前被比较字符与当前索引为i的比较字符不相同时,
|
|
|
|
|
|
//当前被比较字符前移一位,当前比较字符索引回0,重新比较;
|
2026-09-28 15:28:50 +08:00
|
|
|
|
void AString::CreateNextTable(long *next) const
|
|
|
|
|
|
{
|
|
|
|
|
|
if(IsEmpty())
|
|
|
|
|
|
return;
|
|
|
|
|
|
next[0] = -1;
|
|
|
|
|
|
if(Length() == 1)
|
|
|
|
|
|
return;
|
|
|
|
|
|
next[1] = 0;
|
|
|
|
|
|
long lastIndex = Length() - 1;
|
|
|
|
|
|
for(long i = 1,j = 0; i < lastIndex;)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(pData[i] == pData[j])
|
|
|
|
|
|
{
|
|
|
|
|
|
i++;
|
|
|
|
|
|
j++;
|
|
|
|
|
|
if(pData[i] == pData[j])
|
|
|
|
|
|
next[i] = next[j];
|
|
|
|
|
|
else
|
|
|
|
|
|
next[i] = j;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
j = next[j];
|
|
|
|
|
|
if(j == -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
j = 0;
|
|
|
|
|
|
i++;
|
|
|
|
|
|
next[i] = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
long AString::Find(const AString&s,Quene<long>&quene,long from,long to) const
|
|
|
|
|
|
{
|
|
|
|
|
|
if(s.IsEmpty())
|
|
|
|
|
|
return NOT_FOUND;
|
|
|
|
|
|
if(to == -1)
|
|
|
|
|
|
to = Length()-1;
|
|
|
|
|
|
long *next = new long[s.Length()];
|
|
|
|
|
|
s.CreateNextTable(next);
|
|
|
|
|
|
for(long i = from,j = 0; i <= to;)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(pData[i] == s[j])
|
|
|
|
|
|
{
|
|
|
|
|
|
i++;
|
|
|
|
|
|
j++;
|
|
|
|
|
|
if(j == s.Length())
|
|
|
|
|
|
{
|
|
|
|
|
|
quene.EnQuene(i - j);
|
|
|
|
|
|
j = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
j = next[j];
|
|
|
|
|
|
if(j == -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
j = 0;
|
|
|
|
|
|
i++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
delete[] next;
|
|
|
|
|
|
return quene.GetLength();
|
|
|
|
|
|
}
|
|
|
|
|
|
long AString::Replace(const AString&s,const AString&d,long from,long to)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(to == -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
to = Length()-1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ListQuene<long>quene;
|
|
|
|
|
|
long num = Find(s,quene,from,to);
|
|
|
|
|
|
|
|
|
|
|
|
if(num != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
long oldLength = Length();
|
|
|
|
|
|
length = oldLength + num * (d.Length() - s.Length()) + 1;
|
|
|
|
|
|
char *pTemp = pData;
|
|
|
|
|
|
pData = new char[length];
|
|
|
|
|
|
Clear();
|
|
|
|
|
|
long i,j = 0;
|
|
|
|
|
|
while(quene.DeQuene(i))
|
|
|
|
|
|
{
|
|
|
|
|
|
Copy(pTemp + j, m_nEnd,i - j);
|
|
|
|
|
|
*this << d;
|
|
|
|
|
|
j = i + s.Length();
|
|
|
|
|
|
}
|
|
|
|
|
|
Copy(pTemp + j, m_nEnd, oldLength - j);
|
|
|
|
|
|
delete[] pTemp;
|
|
|
|
|
|
}
|
|
|
|
|
|
return num;
|
|
|
|
|
|
}
|
2026-10-04 00:04:20 +08:00
|
|
|
|
//支持通配符的查找替换
|
2026-09-28 15:28:50 +08:00
|
|
|
|
long AString::FindEx(const AString&sFindRule,AString &res,int flag,long from,long to) const
|
|
|
|
|
|
{
|
|
|
|
|
|
return NOT_FOUND;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AString::ReplaceEx(const AString&sFindRule,const AString&sReplaceRule,int flag)
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool AString::Insert(long i,const AString&s)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(i >= 0 && i <= m_nEnd)
|
|
|
|
|
|
{
|
|
|
|
|
|
AString temp = Right(m_nEnd - i);
|
|
|
|
|
|
SetEnd(i);
|
|
|
|
|
|
*this<<s<<temp;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|