FreeScan/MABString.cpp

900 lines
21 KiB
C++

// Base code is derivitive of Zafir's CString class found on the www.CodeGuru.com site.
/* For future reference from a post from 2008 in codeguru:
Zapper, that article is 9 YEARS OLD.
The missing features referred to by the article to have long been implemented in CString.
In addition, back then CString had a dependency on MFC, but since Visual C++ 2005,
his dependency has been removed and MFC is no longer required to use CString. The underlying
CString functionality is implemented by CStringT and you just need to include "atlstr.h" to use it in your app.
You can read all about the CStringT class in msdn.
P.S. Don't use CStringT directly, just include "atlstr.h" and
use CString (including the header will properly typedef CStringT into CString for you).
*/
#include "StdAfx.h"
#include "MABString.h"
#include "math.h"
#include "float.h"
// Insert - Inserts a sub string into the string
// Returns - Reference to the same string object
// pos - Position to insert at. Extends the string with spaces if needed
// s - Sub string to insert
CStringEx& CStringEx::Insert(int pos, LPCTSTR s)
{
int len = lstrlen(s);
if ( len == 0 )
return *this;
int oldlen = GetLength();
int newlen = oldlen + len;
LPTSTR str;
if ( pos >= oldlen )
{
// insert after end of string
newlen += pos - oldlen ;
str = GetBuffer( newlen );
_tcsnset_s( str+oldlen,newlen, _T(' '), pos-oldlen );
_tcsncpy_s( str+pos,newlen, s, len );
}
else
{
// normal insert
str = GetBuffer( newlen );
memmove( str+pos+len, str+pos, sizeof(_T(' ')) *(oldlen-pos) );
_tcsncpy_s( str+pos, newlen, s, len );
}
ReleaseBuffer( newlen );
return *this;
}
// Insert - Inserts a character into the string
// Returns - Reference to the same string object
// pos - Position to insert at. Extends the string with spaces if needed
// c - Char to insert
CStringEx& CStringEx::Insert(int pos, TCHAR c)
{
TCHAR buf[2];
buf[0] = c;
buf[1] = _T('\0');
return Insert( pos, buf );
}
// Delete - Deletes a segment of the string and resizes it
// Returns - Reference to the same string object
// pos - Position of the string segment to remove
// len - Number of characters to remove
CStringEx& CStringEx::Delete(int pos, int len)
{
int strLen = GetLength();
if( pos >= strLen)
return *this;
if(len < 0 ||len > strLen - pos)
len = strLen - pos;
LPTSTR str = GetBuffer( strLen );
memmove(str+pos, str+pos+len, sizeof(_T(' ')) *(strLen-pos));
ReleaseBuffer( strLen - len );
return *this;
}
// Replace - Replaces a substring with another
// Returns - Reference to the same string object
// pos - Position of the substring
// len - Length of substring to be replaced
// s - New substring
CStringEx& CStringEx::Replace(int pos, int len, LPCTSTR s)
{
Delete(pos, len);
Insert(pos, s);
return *this;
}
// Find - Finds the position of a character in a string
// Returns - A zero-based index
// ch - Character to look for
// startpos - Position to start looking from
int CStringEx::Find( TCHAR ch, int startpos /*= 0*/ ) const
{
// find first single character
LPTSTR lpsz = _tcschr((LPTSTR)GetString() + startpos, (_TUCHAR)ch);
// return -1 if not found and index otherwise
return (lpsz == NULL) ? -1 : (int)(lpsz - GetString());
}
// Find - Finds the position of a substring in a string
// Returns - A zero-based index
// lpszSub - Substring to look for
// startpos - Position to start looking from
int CStringEx::Find( LPCTSTR lpszSub, int startpos /*= 0*/ ) const
{
ASSERT(AfxIsValidString(lpszSub, FALSE));
// find first matching substring
LPTSTR lpsz = _tcsstr((LPTSTR)GetString()+startpos, lpszSub);
// return -1 for not found, distance from beginning otherwise
return (lpsz == NULL) ? -1 : (int)(lpsz - GetString());
}
// FindNoCase - Case insensitive find
// Returns - A zero-based index
// ch - Char to search for
// startpos - Position to start looking from
int CStringEx::FindNoCase( TCHAR ch, int startpos /*= 0*/ ) const
{
unsigned int locase = Find( tolower( ch ), startpos );
unsigned int upcase = Find( toupper( ch ), startpos );
return locase < upcase ? locase : upcase;
}
// FindNoCase - Case insensitive find
// Returns - A zero-based index
// lpszSub - Substring to search for
// startpos - Position to start looking from
int CStringEx::FindNoCase( LPCTSTR lpszSub, int startpos /*= 0*/ ) const
{
CStringEx sLowerThis = *this;
sLowerThis.MakeLower();
CStringEx sLowerSub = lpszSub;
sLowerSub.MakeLower();
return sLowerThis.Find( sLowerSub, startpos );
}
// FindReplace - Find a substring and replace with another
// Returns - Number of instances replaced
// lpszSub - Substring to look for
// lpszReplaceWith - Substring to replace with
// bGlobal - Flag to indicate whether all occurances
// should be replaced
int CStringEx::FindReplace( LPCTSTR lpszSub, LPCTSTR lpszReplaceWith,
BOOL bGlobal /*= TRUE*/ )
{
int iReplaced = 0;
// find first matching substring
LPTSTR lpsz;
int pos = 0;
int lenSub = lstrlen( lpszSub );
int lenReplaceWith = lstrlen( lpszReplaceWith );
while( (lpsz = _tcsstr((LPTSTR)GetString() + pos, lpszSub)) != NULL )
{
pos = (int)(lpsz - (LPTSTR)GetString());
Replace( pos, lenSub, lpszReplaceWith );
pos += lenReplaceWith;
iReplaced++;
if( !bGlobal ) break;
}
return iReplaced;
}
// FindReplaceNoCase - Find a substring and replace with another
// Does case insensitive search
// Returns - Number of instances replaced
// lpszSub - Substring to look for
// lpszReplaceWith - Substring to replace with
// bGlobal - Flag to indicate whether all occurances
// should be replaced
int CStringEx::FindReplaceNoCase( LPCTSTR lpszSub, LPCTSTR lpszReplaceWith,
BOOL bGlobal /*= TRUE*/ )
{
CStringEx sLowerThis = *this;
sLowerThis.MakeLower();
CStringEx sLowerSub = lpszSub;
sLowerSub.MakeLower();
int iReplaced = 0;
// find first matching substring
LPTSTR lpsz;
int pos = 0, offset = 0;
int lenSub = lstrlen( lpszSub );
int lenReplaceWith = lstrlen( lpszReplaceWith );
while( (lpsz = _tcsstr((LPTSTR)sLowerThis.GetString() + pos, (LPTSTR)sLowerSub.GetString()))
!= NULL )
{
pos = (int)(lpsz - (LPTSTR)sLowerThis.GetString());
Replace( pos+offset, lenSub, lpszReplaceWith );
offset += lenReplaceWith - lenSub;
pos += lenSub;
iReplaced++;
if( !bGlobal ) break;
}
return iReplaced;
}
// ReverseFind - Searches for the last match of a substring
// Returns - A zero-based index
// lpszSub - Substring to search for
// startpos - Position to start looking from, in reverse dir
int CStringEx::ReverseFind( LPCTSTR lpszSub, int startpos /*= -1*/ ) const
{
int lenSub = lstrlen( (LPTSTR)GetString() );
int len = lstrlen( (LPTSTR)GetString() );
if(0 < lenSub && 0 < len)
{
if( startpos == -1 || startpos >= len ) startpos = len - 1;
for ( LPTSTR lpszReverse = (LPTSTR)GetString() + startpos ;
lpszReverse != (LPTSTR)GetString() ; --lpszReverse)
if (_tcsncmp(lpszSub, lpszReverse, lenSub ) == 0)
return (lpszReverse - (LPTSTR)GetString());
}
return -1;
}
// ReverseFindNoCase - Searches for the last match of a substring
// Search is case insensitive
// Returns - A zero-based index
// lpszSub - Character to search for
// startpos - Position to start looking from, in reverse dir
int CStringEx::ReverseFindNoCase(TCHAR ch, int startpos /*= -1*/ ) const
{
TCHAR a[3];
a[1] = ch;
a[2] = 0;
return ReverseFindNoCase( a, startpos );
}
// ReverseFindNoCase - Searches for the last match of a substring
// Search is case insensitive
// Returns - A zero-based index
// lpszSub - Substring to search for
// startpos - Position to start looking from, in reverse dir
int CStringEx::ReverseFindNoCase( LPCTSTR lpszSub, int startpos /*= -1*/ )
const
{
//LPTSTR lpszEnd = m_pchData + lstrlen
int lenSub = lstrlen( lpszSub );
int len = lstrlen( (LPTSTR)GetString() );
if(0 < lenSub && 0 < len)
{
if( startpos == -1 || startpos >= len ) startpos = len - 1;
for ( LPTSTR lpszReverse = (LPTSTR)GetString() + startpos ;
lpszReverse >= (LPTSTR)GetString() ; --lpszReverse)
if (_tcsnicmp(lpszSub, lpszReverse, lenSub ) == 0)
return (lpszReverse - (LPTSTR)GetString());
}
return -1;
}
// GetField - Gets a delimited field
// Returns - A CStringEx object that contains a copy of
// the specified field
// delim - The delimiter string
// fieldnum - The field index - zero is the first
// NOTE - Returns the whole string for field zero
// if delim not found
// Returns empty string if # of delim found
// is less than fieldnum
CStringEx CStringEx::GetField( LPCTSTR delim, int fieldnum)
{
LPTSTR lpsz, lpszRemainder = (LPTSTR)GetString(), lpszret;
int retlen, lenDelim = lstrlen( delim );
while( fieldnum-- >= 0 )
{
lpszret = lpszRemainder;
lpsz = _tcsstr(lpszRemainder, delim);
if( lpsz )
{
// We did find the delim
retlen = lpsz - lpszRemainder;
lpszRemainder = lpsz + lenDelim;
}
else
{
retlen = lstrlen( lpszRemainder );
lpszRemainder += retlen; // change to empty string
}
}
return Mid( lpszret - (LPTSTR)GetString(), retlen );
}
// GetField - Gets a delimited field
// Returns - A CStringEx object that contains a copy of
// the specified field
// delim - The delimiter char
// fieldnum - The field index - zero is the first
// NOTE - Returns the whole string for field zero
// if delim not found
// Returns empty string if # of delim found
// is less than fieldnum
CStringEx CStringEx::GetField( TCHAR delim, int fieldnum)
{
LPTSTR lpsz, lpszRemainder = (LPTSTR)GetString(), lpszret;
int retlen;
while( fieldnum-- >= 0 )
{
lpszret = lpszRemainder;
lpsz = _tcschr(lpszRemainder, (_TUCHAR)delim);
if( lpsz )
{
// We did find the delim
retlen = lpsz - lpszRemainder;
lpszRemainder = lpsz + 1;
}
else
{
retlen = lstrlen( lpszRemainder );
lpszRemainder += retlen; // change to empty string
}
}
return Mid( lpszret - (LPTSTR)GetString(), retlen );
}
// GetFieldCount - Get number of fields in a string
// Returns - The number of fields
// Is always greater than zero
// delim - The delimiter character
int CStringEx::GetFieldCount( TCHAR delim )
{
TCHAR a[2];
a[0] = delim;
a[1] = 0;
return GetFieldCount( a );
}
// GetFieldCount - Get number of fields in a string
// Returns - The number of fields
// Is always greater than zero
// delim - The delimiter string
int CStringEx::GetFieldCount( LPCTSTR delim )
{
LPTSTR lpsz, lpszRemainder = (LPTSTR)GetString();
int lenDelim = lstrlen( delim );
int iCount = 1;
while( (lpsz = _tcsstr(lpszRemainder, delim)) != NULL )
{
lpszRemainder = lpsz + lenDelim;
iCount++;
}
return iCount;
}
// GetDelimitedField - Finds a field delimited on both ends
// Returns - A CStringEx object that contains a copy of
// the specified field
// delimStart - Delimiter at the start of the field
// delimEnd - Delimiter at the end of the field
CStringEx CStringEx::GetDelimitedField( LPCTSTR delimStart, LPCTSTR
delimEnd, int fieldnum /*= 0*/)
{
LPTSTR lpsz, lpszEnd, lpszRet, lpszRemainder = (LPTSTR)GetString() ;
int lenDelimStart = lstrlen( delimStart ), lenDelimEnd = lstrlen( delimEnd
);
while( fieldnum-- >= 0 )
{
lpsz = _tcsstr(lpszRemainder, delimStart);
if( lpsz )
{
// We did find the Start delim
lpszRet = lpszRemainder = lpsz + lenDelimStart;
lpszEnd = _tcsstr(lpszRemainder, delimEnd);
if( lpszEnd == NULL ) return"";
lpszRemainder = lpsz + lenDelimEnd;
}
else return "";
}
return Mid( lpszRet - (LPTSTR)GetString(), lpszEnd - lpszRet );
}
BOOL CStringEx::IsFloat()
{
if(!Find(".")) return FALSE;
return TRUE;
}
BOOL CStringEx::IsInt()
{
if(Find(".")) return FALSE;
return TRUE;
}
void CStringEx::PutFloat(float value, int len, char ExpChar)
{
switch (_fpclass(value))
{
case _FPCLASS_SNAN:
case _FPCLASS_QNAN:
Format("%s", m_csNAN); // "NaN"
return;
case _FPCLASS_NINF:
Format("%s", m_csNINF);// "-Inf"
return;
case _FPCLASS_PINF:
Format("%s", m_csPINF);// "+Inf"
return;
}
PutDouble((double)value, len, ExpChar);
// have we exceeded our acuracy?
int acc = 8;
if(len< acc+1) return;
Accuracy(acc,(int)ExpChar);
}
void CStringEx::Accuracy(int acc,int ExpAscii)
{
int len = GetLength();
int i=0,i1;
if(GetAt(i)==35) return;
while(GetAt(i)==48 || GetAt(i)==45 || GetAt(i)==46)
{
if (GetAt(i)==ExpAscii) return;
i++;
if (i>=len) break;
}
i1=i-1;
if(acc+i1+1>len) i1=len-acc-1;
while(i<=acc+i1)
{
if(GetAt(i)==ExpAscii) return;
i++;
}
if(Find('.') > i-acc && Find('.') < i) i++;
for(;i<len;i++)
{
if(GetAt(i)==ExpAscii) return;
if(GetAt(i)!=46) SetAt(i,'0');
}
}
void CStringEx::PutFloatS(float value, int nsignificands, char ExpChar)
{
// Code From
// Copyright SOCABIM 1999
// Pierre Caussin
// Jean-Paul Retru
switch (_fpclass(value))
{
case _FPCLASS_SNAN:
case _FPCLASS_QNAN:
Format("%s", m_csNAN); // "NaN"
return;
case _FPCLASS_NINF:
Format("%s", m_csNINF);// "-Inf"
return;
case _FPCLASS_PINF:
Format("%s", m_csPINF);// "+Inf"
return;
}
PutDoubleS((double) value, nsignificands, ExpChar);
int acc = 8;
if(nsignificands< acc+1) return;
Accuracy(acc,(int)ExpChar);
return;
}
void CStringEx::PutDoubleS(double value, int nsignificands, char ExpChar)
{
Empty( );
// Code From
// Copyright SOCABIM 1999
// Pierre Caussin
// Jean-Paul Retru
CString fmt;
int nk;
switch (_fpclass(value))
{
case _FPCLASS_SNAN:
case _FPCLASS_QNAN:
Format("%s", m_csNAN); // "NaN"
return;
case _FPCLASS_NINF:
Format("%s", m_csNINF);// "-Inf"
return;
case _FPCLASS_PINF:
Format("%s", m_csPINF);// "+Inf"
return;
case _FPCLASS_NN:
case _FPCLASS_PN:
nk = (int)log10(fabs(value));
if (fabs(value)<1) nk--;
if (nk > nsignificands-1 || nk < -2)
{
fmt.Format("%%.%df%c%d",nsignificands-1,ExpChar,nk);
Format(fmt,value/pow(10.,nk));
}
else
{
if (nk == nsignificands-1 && nk>1)
fmt.Format("%%.%df.",0);
else
fmt.Format("%%.%df",nsignificands>nk+1?nsignificands-nk-1:0);
Format(fmt,value);
}
return;
default:
fmt.Format("%%.%df",nsignificands);
Format(fmt,0.);
}
int acc = 16;
Accuracy(acc,(int)ExpChar);
return;
}
void CStringEx::PutDouble(double value, int len, char ExpChar)
{
Empty( );
switch (_fpclass(value))
{
case _FPCLASS_SNAN:
case _FPCLASS_QNAN:
Format("%s", m_csNAN); // "NaN"
return;
case _FPCLASS_NINF:
Format("%s", m_csNINF);// "-Inf"
return;
case _FPCLASS_PINF:
Format("%s", m_csPINF);// "+Inf"
return;
}
dtoan(GetBuffer(len+1),value,len);
ReleaseBuffer(len+1);
// have we exceeded our acuracy?
// This line replaces the "E" with the users exponent definition.
if(Find('E')>0 && ExpChar!=69) SetAt(Find('E')-1,ExpChar);
int acc = 16;
if(len< acc+1) return;
Accuracy(acc,(int)ExpChar);
}
void CStringEx::PutLong(long i, int len)
{
Empty( );
if(i>=0)
{
if(ltoan(GetBuffer(len),i,len))
ReleaseBuffer(len);
else
{
ReleaseBuffer(len);
Format("Error");
}
}
else
{
ltoan(GetBuffer(len),abs(i),len);
ReleaseBuffer(len);
i=0;
while(GetAt(i)==32) i++;
if(i>0) SetAt(i-1,'-');
else Format("Error");
}
}
void CStringEx::PutInt(int i, int len)
{
PutLong((long)i,len);
}
float CStringEx::GetFloat()
{
TestExp();
float f;
f = atofn(GetBuffer(GetLength()),GetLength());
return f;
}
double CStringEx::GetDouble()
{
TestExp();
double f;
f = atodn(GetBuffer(GetLength()),GetLength());
return f;
}
long CStringEx::GetLong()
{
long f;
f = atoln(GetBuffer(GetLength()),GetLength());
return f;
}
int CStringEx::GetInt()
{
return atoin(GetBuffer(GetLength()),GetLength());
}
inline double CStringEx::atodn(char alpha[],int n)
{
double val;
char format[16];
char string[32];
sprintf_s(format,"%c%df",'%',n);
if(n>32) n=32;
strncpy_s(string,alpha,n);
string[n]='\0';
val=atof(string);//0.0;
//sscanf(string,format,&val);
return (val);
}
inline float CStringEx::atofn(char *alpha,int n)
{
float val;
char format[16];
char string[32];
sprintf_s(format,"%c%df",'%',n);
if(n>32) n=32;
strncpy_s(string,alpha,n);
string[n]='\0';
val=(float)0.;
sscanf_s(string,format,&val);
return (val);
}
inline int CStringEx::atoin(char *alpha,int n)
{
int val;
char format[32];
char string[32];
sprintf_s(format,"%c%dd",'%',n);
val=0;
if(n>32)n=32;
strncpy_s(string,alpha,n);
string[n]='\0';
sscanf_s(string,format,&val);
return (val);
}
inline long int CStringEx::atoln(char alpha[],int n)
{
long int val;
char string[32];
if(n>31) return(0);
strncpy_s(string,alpha,n);
string[n]='\0';
val=atol(string);
return (val);
}
inline void CStringEx::dtoan(char *alpha,double val,int len)
{
if(len<4)
{
AfxMessageBox("Minimum String Length is 4 for error handling!");
return;
}
char format[16];
int exp,i;
unsigned int lenx;
char *temp;
// do we need to use exponential
if(val < 0.0) sprintf_s(format,"%9.2E",val);
else sprintf_s(format,"%9.2E",val);
exp=strlen(&format[6]);
exp=abs(atoin(&format[6],exp));
if( (val>=0 && exp+3 >len) || (val<0 && exp+4 >len) || (exp>2 && fabs(val)<1.0))
{ // use E format
lenx=len+11;
i=sizeof(char);
temp=(char near *)calloc(lenx,i);
if(val < 0.0) sprintf_s(format,"%c%d.%dE",'%',len-1,len-5);
else sprintf_s(format,"%c%d.%dE",'%',len,len-4);
sprintf_s(temp,sizeof(temp),format,val);
lenx=strlen(temp);
i=lenx-3;
do {
if(temp[i]=='0') strcpy_s(&temp[i],sizeof(temp),&temp[i+1]);
} while(i<(int)strlen(temp) && temp[i]=='0');
do {
i--;
} while(i>0 && temp[i]!='E');
if(temp[i]=='E' && temp[i+1]=='+') strcpy_s(&temp[i+1],sizeof(temp),&temp[i+2]);
while (len < (int) strlen(temp) && i>3)
{
i--;
strcpy_s(&temp[i],sizeof(temp),&temp[i+1]);
}
if((int)strlen(temp)>len) strcpy_s(alpha,sizeof(temp),"ERR");
else strcpy_s(alpha,sizeof(temp),temp);
free(temp);
}
else
{ // use f format
if(val < 0.0f) sprintf_s(format,16, "%c%d.%df",'%',len-1,len-3-exp);
else if (val< 0.) sprintf_s(format,16, "%c%d.%df",'%',len,len-3);
else if (val< 1.) sprintf_s(format,16, "%c%d.%df",'%',len,len-2);
else sprintf_s(format,16, "%c%d.%df",'%',len,len-2-exp);
sprintf_s(alpha,sizeof(alpha),format,val);
}
return;
}
/*
inline void CStringEx::ftoan(char *alpha,float val,int len)
{
char format[16];
int exp,i;
unsigned int lenx;
char *temp;
// do we need to use exponential
if(val < 0.0) sprintf_s(format,"%7.2E",val);
else sprintf_s(format,"%8.2E",val);
exp=strlen(&format[6]);
exp=atoin(&format[6],exp);
if( (val>=0 && exp+3 >len) || (val<0 && exp+4 >len) || (exp>2 && fabs(val)<1.0))
{ // use E format
lenx=len+7;
i=sizeof(char);
temp=(char near *)calloc(lenx,i);
if(val < 0.0) sprintf_s(format,"%c%d.%dE",'%',len-1,len-5);
else sprintf_s(format,"%c%d.%dE",'%',len,len-4);
sprintf_s(temp,format,val);
lenx=strlen(temp);
i=lenx-2;
do {
if(temp[i]=='0') strcpy(&temp[i],&temp[i+1]);
else i--;
} while(i>0 && temp[i]!='E');
if(temp[i]=='E' && temp[i+1]=='+') strcpy(&temp[i+1],&temp[i+2]);
while (len < (int) strlen(temp))
{
i--;
strcpy(&temp[i],&temp[i+1]);
}
strcpy(alpha,temp);
free(temp);
}
else
{ // use f format
if(val < -1.0) sprintf_s(format,"%c%d.%df",'%',len-1,len-3-exp);
else if (val< 0.) sprintf_s(format,"%c%d.%df",'%',len-1,len-3);
else if (val< 1.) sprintf_s(format,"%c%d.%df",'%',len,len-2);
else sprintf_s(format,"%c%d.%df",'%',len,len-2-exp);
sprintf_s(alpha,format,val);
}
return;
}
*/
inline void CStringEx::itoan(char alpha[],int n,int l)
{
int val;
int count;
char item;
for (count=1;count<=l;count++)
{
val=n-(n/10)*10;
_itoa_s(val,&item,sizeof(item),10);
alpha[l-count]=item;
n=n/10;
}
count=0;
while ((int)alpha[count]==48 && count<l-1)
{
alpha[count]=' ';
count++;
}
return;
}
inline BOOL CStringEx::ltoan(char alpha[],long int n,int l)
{
long int val;
int count;
char item;
BOOL ret=FALSE;
for (count=1;count<=l;count++)
{
val=n-(n/10)*10;
_ltoa_s(val,&item,sizeof(item),10);
alpha[l-count]=item;
n=n/10;
}
if(n==0) ret=TRUE;
count=0;
while ((int)alpha[count]==48 && count<l-1)
{
alpha[count]=' ';
count++;
}
return ret;
}
/*
inline int CStringEx::sizestr(char string[],int max)
{
int i;
for(i=0;i<max;i++)
{
if(string[i]=='\0') return(i);
}
return(max);
}
inline void CStringEx::stradd(char stringto[],int maxto,char stringfrom[],int maxfrom)
{
int l1,l2,i;
l1=sizestr(stringto,maxto);
l2=sizestr(stringfrom,maxfrom);
for(i=0;i<=l2;i++) stringto[l1+i]=stringfrom[i];
return;
}
inline void CStringEx::strfill(char string[],int max,char fill)
// max is length of string including null terminator
{
int l1,i;
string[max-1]='\0';
l1 = sizestr(string,max);
// /* l1 is length of the string
// this matchs the position
// of the null terminator
for(i=l1;i<=max-2;i++) string[i]=fill;
string[max-1]='\0';
return;
}
inline void CStringEx::strover(char stringto[],char stringfrom[],int maxfrom)
{
int l2,i;
l2=sizestr(stringfrom,maxfrom)-1;
for(i=0;i<=l2;i++) stringto[i]=stringfrom[i];
return;
}
*/
void CStringEx::TestExp()
{
int pos;
pos = max(ReverseFind('-'),ReverseFind('+'));
if(pos<2) return;
if(GetAt(pos-1)==32) return;
if(GetAt(pos-1)==69 || GetAt(pos-1)==101) return;
Insert(pos-1,'E');
}
// The following code from
// Copyright SOCABIM 1999
// Pierre Caussin
// Jean-Paul Retru
CString CStringEx::m_csNAN("NaN");
CString CStringEx::m_csNINF("-Inf");
CString CStringEx::m_csPINF("+Inf");