📄 scstring.hpp
字号:
#ifndef SCSTR_HPP#define SCSTR_HPP// A simple string type for Ansi/Unicode// Expects a type scChar to be defined// Also expects that ExpArr.hpp is included at this point#include <string.h>#include <stdio.h>#include <ctype.h>#ifndef SCCHAR_TYPEDEF #ifndef scChar #warning scChar not defined, defaulting to char #define scChar char #endif #endif#ifndef scInt // For string length #define scInt int#endif/*#ifndef EA_ASSERT #define EA_ASSERT assert #include <assert.h>#endif*/#include "ExpArr.hpp"#include "sc.h"#ifndef STR_AT_END #define STR_AT_END ((int)0x80000000)#endifclass scString : public ExpArr<scChar,scInt> {public: scString( const scChar *ps=NULL ) : ExpArr<scChar,scInt>(ps,ps?(int)scstrlen(ps):0) { Push((scChar)0); } scString( const scString &s ) : ExpArr<scChar,scInt>(s) { } scString( const scChar *ps, int len ) : ExpArr<scChar,scInt>( ps, len<0? (ps?scstrlen(ps):0) :len ) { Push(0); } // Concatenation constructor scString( const scChar *ps1, const scChar *ps2, int l1=-1, int l2=-1 ) { if(l1==-1) l1 = ps1?(int)scstrlen(ps1):0; if(l2==-1) l2 = ps2?(int)scstrlen(ps2):0; MinTotalSize(l1+l2+1); Push( ps1,l1 ); Push( ps2,l2 ); Push(0); } // Construct from an interval (begin end) scString( bool dummy, const scChar *ps, const scChar *pe) : ExpArr<scChar,scInt>() { Assign(ps,pe); } // To allow quick formatting of an int scString( bool dummy, int i, const char *fmt=NULL ){ char buf[64]; sprintf(buf,fmt?fmt:"%d",i); Assign(buf); } // To allow quick formatting of a double scString( bool dummy, double d, const char *fmt=NULL ){ char buf[64]; sprintf(buf,fmt?fmt:"%e",d); Assign(buf); } scString &Assign(const scChar *ps, int l=-1){ ExpArr<scChar,scInt>::Empty(); Push(ps, ps ? (l<0?(int)scstrlen(ps):l) : 0); Push((scChar)0); return *this; } scString &Assign(const scChar *ps, const scChar *pend ){ return Assign( ps, ps && pend ? pend-ps : -1 ); } scString &operator = (const scString &s){ return Assign(s,s.Length()); //ExpArr<scChar,scInt>::Empty(); //Push(s.Base(),s.ExpArr<scChar,scInt>::Size()); //return *this; } scString &operator = (const scChar *ps){ return Assign(ps,-1); //ExpArr<scChar,scInt>::Empty(); //Push(ps,ps?scstrlen(ps):0); //Push((scChar)0); //return *this; } operator const scChar*() const { return ta; } scString &operator += (const scChar *ps ){ return Append(ps,-1); //if(!ps) return *this; //Pop(); //Push(ps,scstrlen(ps)+1); //return *this; } scString &operator += (const scString &s ){ Pop(); Push(s.Base(),s.ExpArr<scChar,scInt>::Size()); return *this; } scString &Insert(int at, const scChar *ps, int len=-1){ if(!ps || !len) return *this; if( at==(int)STR_AT_END ) at = cur_size-1; else{ at %= cur_size; // Including NUL if( at<0 ) at += cur_size-1; } ExpArr<scChar,scInt>::Insert( ps, len<0?(int)scstrlen(ps):len, at ); return *this; } scString &Append(const scChar *ps, int len=-1){ return Insert(STR_AT_END,ps,len); } scString &Append(scChar ch){ ta[cur_size-1] = ch; Push((scChar)0); return *this; } scString &Prepend(const scChar *ps, int len=-1){ return Insert(0,ps,len); } scString &Prepend(scChar ch){ InsertOrdered( ch,0 ); return *this; } scString &operator += (const scChar ch ){ return Append(ch); }/* scString operator + (const scChar *ps) { return scString(ta,ps,cur_size-1); }*/ bool operator == (const scChar *ps ) const { if(!ps) return !Length(); return !scstrcmp(ta,ps); } bool operator == (scChar *ps ) const { if(!ps) return !Length(); return !scstrcmp(ta,ps); } bool operator != (const scChar *ps ) const { return ! operator == (ps); } // Use base case //scChar &operator [] (int ix) { EA_ASSERT(ix<Length()); return Elem(ix); } int Length() const { return cur_size-1; } int Size() const { return cur_size-1; } // Basically to hide ExpArr::Empty // Basically to hide ExpArr::SetSize bool SetSize( int len ) { bool b = ExpArr<scChar,scInt>::SetSize(len); if( !b ) return false; Push(0); return true; } scString &operator += (int i ){ scChar buf[16]; sprintf(buf,_SC("%d"),i); return *this+=buf; } scString &operator += (double d ){ scChar buf[32]; sprintf(buf,_SC("%f"),d); return *this+=buf; } scString &operator = (int i ){ scChar buf[16]; sprintf(buf,_SC("%d"),i); return *this=buf; } scString &operator = (double d ){ scChar buf[32]; sprintf(buf,_SC("%f"),d); return *this=buf; } scString &Trunc(int pos){ if( pos<0 ) pos = Length()+pos; if( pos<0 || pos>=Length() ) EA_THROW_RV("scString::Trunc - Invalid pos", *this); //EA_ASSERT(pos>=0 && pos<Length()); cur_size = pos; Push((scChar)0); return *this; } scString &SetLength( int len ) { if(len<=Length()) return Trunc(len); MinTotalSize( len+1 ); cur_size = len; Push((scChar)0); return *this; } scChar *Right( int from_pos ){ if( from_pos<0 ) from_pos = Length()+from_pos; if( from_pos<0 || from_pos>=Length() ) return NULL; return ta+from_pos; } scString &Strip( bool left=true, bool right=true ) { int p_left=0, p_right=cur_size-2; if( left ) for( ; p_left<cur_size && scisspace(ta[p_left]); p_left++ ); if( right ) for( ; p_right>=0 && scisspace(ta[p_right]); p_right-- ); if( p_left>p_right ) return Reset(); if( p_left ) memmove(ta,ta+p_left,p_right+1-p_left); ta[p_right+1-p_left] = (scChar)0; cur_size = p_right+2-p_left; return *this; } scString &Reset( ){ ExpArr<scChar,scInt>::Empty(); Push((scChar)0); return *this; } scString &Empty( ){ // Basically to hide ExpArr::Empty return Reset(); } int Subst( scChar find, scChar repl ){ int n_found = 0; for( int ix=cur_size-2; ix>=0; ix-- ) if( ta[ix]==find ){ ta[ix]=repl; n_found++; } return n_found; } int Subst( const char *find, const char *repl ){ int n_found = 0; if( find!=repl && find && *find ){ int pos = 0; int rl = repl?(int)strlen(repl):0; int dl = rl - (int)strlen(find); while( 1 ){ char *pc = strstr(ta+pos,find); if( !pc ) break; pos = pc-ta; if( dl<0 ) // Remove space from array ExpArr<char>::Remove( -dl, pos ); else if( dl>0 ) // Insert space //ExpArr<char>::Insert(repl,dl,pos); ExpArr<char>::MakeSpaceAt( pos, dl ); if( rl ) memcpy(ta+pos,repl,rl); n_found++; pos += rl; } } return n_found; } bool FindAt( const scChar *str, int pos=0/*STR_AT_END for find at end*/ ){ if( !str || !ta || pos>=cur_size ) return false; int sl = (int)strlen(str); if( pos>=0 ) return !strncmp(ta+pos,str,sl); else{ if( pos==STR_AT_END ) pos = 0; int dp = cur_size+pos-1-sl; if( dp<0 ) return false; return !strncmp(ta+dp,str,sl); } } bool StartsWith( const scChar *psc ){ return FindAt( psc,0 ); } bool EndsWith( const scChar *psc ){ return FindAt( psc,STR_AT_END ); } int Find( const scChar *psc, bool from_end=false ){ if( !psc ) return -1; scChar *ploc = NULL; if( !from_end ) ploc = scstrstr(ta,psc); else{ int sl = scstrlen(psc); ploc = ta + cur_size-sl; while( ploc>=ta && scstrncmp(psc,ploc,sl) ) ploc--; } return ploc && ploc>=ta? int(ploc-ta) : -1; } scString Slice( int from, int to=STR_AT_END ){ if( from<0 ) from=cur_size-1+from; if( from<0 || from>=Length() ) EA_THROW_RV("scString::Slice - Invalid from", *this); if( to<0 ){ if( to==STR_AT_END ) to = cur_size-1; else to = cur_size+to-1; } if( to!=STR_AT_END && (to<0 || to>=Length()) ) EA_THROW_RV("scString::Slice - Invalid to", *this); if( to<=from ) return scString(); else return scString( ta+from, to-from ); } scString &Suffix( const scChar *psc ){ if( !FindAt(psc,STR_AT_END) ) Append(psc); return *this; } scString &Suffix( scChar ch ){ if( !ta || cur_size<2 || ta[cur_size-2]!=ch ) Append(ch); return *this; } scString &Prefix( const scChar *psc ){ if( !FindAt(psc,0) ) Prepend(psc); return *this; } scString &Prefix( scChar ch ){ if( !ta || *ta!=ch ) Prepend(ch); return *this; } bool SaveToFile( const scChar *path ){ FILE *pf = fopen(path,"w"); if( !pf ) return false; fwrite(Base(),scString::Size(),1,pf); fclose(pf); return true; } bool LoadFromFile( const scChar *path ){ FILE *pf = fopen(path,"r"); if( !pf ) return false; char buf[256]; int rl; Empty(); while( (rl=fread(buf,1,256,pf))>0 ) Append( buf, rl ); fclose(pf); return true; }};//scString operator + (const scChar *ps1, const scString &s2);scString operator + (const scString &s1, const scChar *ps2 );scString operator + (const scString &s1, const scString &s2 ); #endif // SCSTR_HPP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -