//---------------------------------------------------------------------------- // EgalTech 2013-2014 //---------------------------------------------------------------------------- // File : StringUtils.cpp Data : 17.03.14 Versione : 1.5c2 // Contenuto : Implementazione delle funzioni di utilità per le stringhe. // // // // Modifiche : 20.01.13 DS Creazione modulo. // 02.12.13 DS Agg. FromString per Vector3d, Point3d e Point3d+W. // 19.01.14 DS Tokenize con Atom ora funziona su più livelli. // 17.03.14 DS Agg. CurrDateTime. // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "/EgtDEv/Include/EgnStringUtils.h" #include using namespace std ; //---------------------------------------------------------------------------- const string ToString( double dVal, int nPrec) { const double BIG_NUMBER = 1e10 ; const int BIG_DIGITNBR = 10 ; const int MAX_PREC = 12 ; char szBuff[24] ; char szDest[32] ; char* pBuff ; char* pDest ; int nErr ; int nDecimal ; int nSign ; int nExp ; int nTmp ; // verifico la precisione nPrec = min( nPrec, MAX_PREC) ; // converto la mantissa if ( fabs( dVal) < BIG_NUMBER) nErr = _fcvt_s( szBuff, dVal, nPrec, &nDecimal, &nSign) ; else nErr = _ecvt_s( szBuff, dVal, BIG_DIGITNBR + nPrec, &nDecimal, &nSign) ; // se errore, ritorno stringa opportuna if ( nErr != 0) { _ASSERT( 0) ; return "#Error" ; } // se buffer vuoto, risultato è numero 0 if ( szBuff[0] == '\0') return "0" ; // verifica per forma esponenziale if ( nDecimal > BIG_DIGITNBR) { nExp = nDecimal - 1 ; nDecimal = 1 ; } else nExp = 0 ; // puntatori a inizio stringhe pBuff = szBuff ; pDest = szDest ; // eventuale inserimento segno '-' if ( nSign != 0) { *pDest = '-' ; pDest ++ ; } ; // gestione decimali dopo 0 if ( nDecimal <= 0) { *pDest = '0' ; pDest ++ ; *pDest = '.' ; pDest ++ ; for ( ; nDecimal < 0 ; nDecimal ++) { *pDest = '0' ; pDest ++ ; } nDecimal -- ; } // gestione cifre e . while ( *pBuff != '\0') { if ( *pBuff == '#') // NAN, INFINITY, INDEFINITE _ASSERT( 0) ; if ( nDecimal == 0) { *pDest = '.' ; pDest ++ ; } nDecimal -- ; *pDest = *pBuff ; pDest ++ ; pBuff ++ ; } *pDest = '\0' ; // se inserito un punto decimale tolgo i trailing zero if ( nDecimal < 0) { pDest -- ; while ( *pDest == '0') { *pDest = '\0' ; pDest -- ; } if ( *pDest == '.') *pDest = '\0' ; else pDest ++ ; } // aggiungo eventuale esponente (sempre compreso tra 9 e 308) if ( nExp > 0) { *pDest = 'e' ; pDest ++ ; nTmp = nExp ; if ( nTmp >= 100) { *pDest = '0' + ( nTmp / 100) ; pDest ++ ; nTmp = nTmp % 100 ; } if ( nTmp >= 10 || nExp >= 100) { *pDest = '0' + ( nTmp / 10) ; pDest ++ ; nTmp = nTmp % 10 ; } *pDest = '0' + nTmp ; pDest ++ ; *pDest = '\0' ; } if ( szDest[0] == '-' && szDest[1] == '0' && szDest[2] == '\0') return "0" ; else return szDest ; } //---------------------------------------------------------------------------- void Split( const string& sString, const string& sSeparator, bool bFirstVsLast, string& sFirst, string& sLast) { string::size_type iPos ; // cerco il separatore iPos = ( bFirstVsLast ? sString.find( sSeparator) : sString.rfind( sSeparator)) ; // se trovato if ( iPos != string::npos) { if ( iPos > 0) sFirst = sString.substr( 0, iPos) ; else sFirst.clear() ; if ( ( iPos + 1) < sString.length()) sLast = sString.substr( iPos + 1) ; else sLast.clear() ; } // altrimenti else { sFirst = sString ; sLast.clear() ; } } //---------------------------------------------------------------------------- bool Tokenize( const string& sString, const string& sSeparators, STRVECTOR& vsTokens) { string::size_type iPosStart ; string::size_type iPosEnd ; // pulisco il risultato vsTokens.clear() ; // parto dall'inizio iPosStart = ( sString.empty() ? string::npos : 0) ; // mentre esiste un nuovo inizio di token while ( iPosStart != string::npos) { // cerco il primo separatore iPosEnd = sString.find_first_of( sSeparators, iPosStart) ; // aggiungo il token al vettore vsTokens.push_back( sString.substr( iPosStart, iPosEnd - iPosStart)) ; // cerco l'inizio di un nuovo token iPosStart = sString.find_first_not_of( sSeparators, iPosEnd) ; } return true ; } //---------------------------------------------------------------------------- bool Tokenize( const string& sString, const string& sSeparators, const string& sAtomStarts, const string& sAtomEnds, STRVECTOR& vsTokens) { // i separatori devono essere diversi da inizio e fine di atomi if ( sAtomStarts.find_first_of( sSeparators) != string::npos || sAtomEnds.find_first_of( sSeparators) != string::npos) return false ; // pulisco il risultato vsTokens.clear() ; // se la stringa è vuota non c'è niente da cercare if ( sString.empty()) return true ; // parto dall'inizio int nOpenAtom = 0 ; string::size_type iPosStart = 0 ; string::size_type iPosEnd = iPosStart ; // mentre esiste un nuovo carattere while ( iPosEnd < sString.size()) { // trovo separatore non all'interno di un atomo if ( sSeparators.find( sString[iPosEnd]) != string::npos && nOpenAtom <= 0) { // aggiungo il token al vettore vsTokens.push_back( sString.substr( iPosStart, iPosEnd - iPosStart)) ; // passo al carattere successivo ++ iPosEnd ; // imposto nuovo inizio di token iPosStart = ( iPosEnd < sString.size() ? iPosEnd : string::npos) ; } // trovo inizio di atomo else if ( sAtomStarts.find( sString[iPosEnd]) != string::npos) { ++ nOpenAtom ; // passo al carattere successivo ++ iPosEnd ; } // trovo fine di atomo else if ( sAtomEnds.find( sString[iPosEnd]) != string::npos) { -- nOpenAtom ; // passo al carattere successivo ++ iPosEnd ; } // carattere normale, vado oltre else ++ iPosEnd ; } // se è rimasto un ultimo token if ( iPosStart != string::npos) vsTokens.push_back( sString.substr( iPosStart)) ; return true ; } //---------------------------------------------------------------------------- int ReplaceString( std::string& sString, const std::string& sOld, const std::string& sNew) { int nSubs ; size_t pos ; nSubs = 0 ; pos = 0 ; while ( ( pos = sString.find( sOld, pos)) != std::string::npos) { sString.replace( pos, sOld.length(), sNew) ; pos += sNew.length() ; nSubs ++ ; } return nSubs ; } //---------------------------------------------------------------------------- const string CurrDateTime( void) { time_t nClock ; tm newTime ; time( &nClock) ; localtime_s( &newTime, &nClock) ; char strDate[10] = { '\0'} ; char strTime[10] = { '\0'} ; _strdate_s( strDate) ; _strtime_s( strTime) ; string sDT = strDate + string( " ") + strTime ; return sDT ; }