StdStringUtils.cpp

Go to the documentation of this file.
00001 /**
00002 \file     StdStringUtils.cpp
00003 \brief    Additional functions for std::string.
00004 
00005 Useful string functions and emulating some function calls 
00006 used by MFC CString. 
00007 
00008 [1]. Microsoft CString MSDN page
00009 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/_mfc_cstring_class_members.asp    
00010 
00011 \author   Glenn D. MacGougan (GDM)
00012 \since    2006-12-20
00013 \date     2007-01-09
00014 
00015 \b "LICENSE INFORMATION" \n
00016 Copyright (c) 2007, refer to 'author' doxygen tags \n
00017 All rights reserved. \n
00018 
00019 Redistribution and use in source and binary forms, with or without
00020 modification, are permitted provided the following conditions are met: \n
00021 
00022 - Redistributions of source code must retain the above copyright
00023   notice, this list of conditions and the following disclaimer. \n
00024 - Redistributions in binary form must reproduce the above copyright
00025   notice, this list of conditions and the following disclaimer in the
00026   documentation and/or other materials provided with the distribution. \n
00027 - The name(s) of the contributor(s) may not be used to endorse or promote 
00028   products derived from this software without specific prior written 
00029   permission. \n
00030 
00031 THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 
00032 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
00033 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00034 DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00035 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00036 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
00037 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
00038 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00039 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00040 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
00041 SUCH DAMAGE.
00042 */
00043 
00044 #include <algorithm>
00045 #include "StdStringUtils.h"
00046 
00047 
00048 //#define _CRT_SECURE_NO_DEPRECATE
00049 
00050 namespace StdStringUtils
00051 {
00052   void SpanExcluding(const std::string &src, const std::string charSet, std::string &dst)
00053   {
00054     std::string::size_type p = 0;
00055     if( src.empty() )
00056       return;
00057 
00058     dst = src;
00059     p = src.find_first_of( charSet );
00060     if( p != std::string::npos )
00061       dst.erase(p);
00062   }
00063 
00064   void SpanExcluding(const std::string &src, const std::string charSet, std::string &dst, std::string::size_type& pos)
00065   {
00066     int index;
00067     std::string::size_type p = 0;
00068     if( src.empty() )
00069       return;
00070 
00071     dst = src;
00072     p = src.find_first_of( charSet );
00073     if( p != std::string::npos )
00074     {
00075       dst.erase(p);
00076       pos = src.find_first_not_of( charSet, p );
00077       index = static_cast<int>(pos-1);
00078       if( index < 0 )
00079       {
00080         pos = 0;
00081       }
00082       else
00083       {
00084         pos = pos-1;
00085       }
00086     }
00087     else
00088     {
00089       pos = std::string::npos;
00090     }
00091   }
00092 
00093 
00094   void SpanNotExcluding(const std::string &src, const std::string charSet, std::string &dst, std::string::size_type& pos)
00095   {
00096     std::string::size_type p = 0;
00097     if( src.empty() )
00098       return;
00099 
00100     dst = src;
00101     p = src.find_first_not_of( charSet );
00102     if( p != std::string::npos )
00103     {
00104       dst.erase(p);
00105       pos = p;
00106     }
00107     else
00108     {
00109       pos = std::string::npos;
00110     }
00111   }
00112 
00113   void MakeUpper(std::string &str)
00114   {
00115     std::transform(str.begin(),str.end(),str.begin(),toupper);
00116   }
00117 
00118   void MakeLower(std::string &str)
00119   {
00120     std::transform(str.begin(),str.end(),str.begin(),tolower);
00121   }
00122 
00123   void TrimRight(std::string &str) 
00124   {
00125     std::string::size_type p = 0;
00126     std::string whitespace = " \t\n\f\r";
00127     p = str.find_last_not_of(whitespace);
00128     if( p != std::string::npos )
00129     {
00130       if( p != str.length()-1 ) // check not at the end of the string
00131         str.erase(p+1);
00132     }
00133     else
00134     {
00135       str.erase();
00136     }
00137   }
00138 
00139   void TrimLeft(std::string &str) 
00140   {
00141     std::string::size_type p = 0;
00142     std::string whitespace = " \t\n\f\r";
00143     p = str.find_first_not_of(whitespace);
00144     if( p != std::string::npos )
00145     {
00146       if( p != 0 )
00147         str = str.substr( p );
00148     }      
00149     else
00150     {
00151       str.erase();
00152     }
00153   }
00154 
00155   void TrimLeftAndRight(std::string &str) 
00156   {
00157     TrimLeft(str);
00158     TrimRight(str);
00159   }
00160 
00161   bool GetDouble( const std::string &str, double &value )
00162   {
00163 #ifndef _CRT_SECURE_NO_DEPRECATE
00164     if( sscanf_s( str.c_str(), "%lf", &value) == 1 )
00165     {
00166       return true;
00167     }
00168     else
00169     {
00170       value = 0;
00171       return false;
00172     }
00173 #else    
00174     if( sscanf( str.c_str(), "%lf", &value) == 1 )
00175     { 
00176       return true;
00177     }
00178     else
00179     {
00180       value = 0;
00181       return false;
00182     }
00183 #endif
00184   }
00185   
00186 
00187   bool GetFloat( const std::string &str, float &value )
00188   {
00189 #ifndef _CRT_SECURE_NO_DEPRECATE
00190     if( sscanf_s( str.c_str(), "%f", &value) == 1 )
00191     {
00192       return true;
00193     }
00194     else
00195     {
00196       value = 0;
00197       return false;
00198     }
00199 #else    
00200     if( sscanf( str.c_str(), "%f", &value) == 1 )
00201     {
00202       return true;
00203     }
00204     else
00205     {
00206       value = 0;
00207       return false;
00208     }
00209 #endif
00210   }
00211 
00212   bool GetInt( const std::string &str, int &value )
00213   {
00214 #ifndef _CRT_SECURE_NO_DEPRECATE
00215     if( sscanf_s( str.c_str(), "%i", &value) == 1 )
00216     {
00217       return true;
00218     }
00219     else
00220     {
00221       value = 0;
00222       return false;
00223     }
00224 #else    
00225     if( sscanf( str.c_str(), "%i", &value) == 1 )
00226     {
00227       return true;
00228     }
00229     else
00230     {
00231       value = 0;
00232       return false;
00233     }
00234 #endif
00235   }
00236 
00237   bool GetUnsignedInt( const std::string &str, unsigned &value )
00238   {
00239 #ifndef _CRT_SECURE_NO_DEPRECATE
00240     if( sscanf_s( str.c_str(), "%u", &value) == 1 )
00241     {
00242       return true;
00243     }
00244     else
00245     {
00246       value = 0;
00247       return false;
00248     }
00249 #else    
00250     if( sscanf( str.c_str(), "%u", &value) == 1 )
00251     {
00252       return true;
00253     }
00254     else
00255     {
00256       value = 0;
00257       return false;
00258     }
00259 #endif
00260   }
00261   
00262   bool ExtractField( const std::string &str, const unsigned index, const char delimiter, std::string &field )
00263   {
00264     unsigned i = 0;
00265     std::string::size_type scount = 0;
00266     std::string DelimiterStr;
00267     std::string ExtractStr;
00268 
00269     if( delimiter == 'w' )
00270     {
00271       DelimiterStr = " \t\r\n\f";
00272     }
00273     else
00274     {
00275       DelimiterStr = delimiter;
00276     }
00277     ExtractStr = str;
00278 
00279     for( i = 0; i <= index; i++ )
00280     {
00281       if( scount >= str.length() )
00282       {
00283         ExtractStr.erase();
00284         field.erase();
00285         break;
00286       }
00287       else
00288       {
00289         ExtractStr = str.substr( scount );
00290       }
00291 
00292       SpanExcluding( ExtractStr, DelimiterStr, field );
00293       scount += field.length() + 1; // plus one for the delimiter
00294       if( field.empty() && ExtractStr.empty() )
00295         break; // no more data      
00296     }
00297     if( !ExtractStr.empty() )
00298     {
00299       return true;
00300     }
00301     else
00302     {
00303       field.erase();
00304       return false;
00305     }
00306   }
00307 
00308   bool ExtractFieldInplace( std::string &str, const char delimiter, std::string &field )
00309   {
00310     std::string DelimiterStr;
00311 
00312     if( delimiter == 'w' )
00313     {
00314       DelimiterStr = " \t\r\n\f";
00315     }
00316     else
00317     {
00318       DelimiterStr = delimiter;
00319     }
00320     if( str.empty() )
00321     {
00322       field.erase();
00323       return false;
00324     }
00325     SpanExcluding( str, DelimiterStr, field );      
00326     if( field.length() < str.length() )
00327       str = str.substr( field.length() + 1 );
00328     else
00329       str.erase();
00330 
00331     if( delimiter == 'w' )
00332     {
00333       TrimLeft(str);
00334     }
00335     return true;
00336   }
00337 
00338   void GetBaseName( const std::string str, std::string &BaseName )
00339   {
00340     std::string::size_type p = 0;
00341     p = str.find_last_of( "." );
00342     if( p == std::string::npos )      
00343     {
00344       BaseName = str;
00345     }
00346     else
00347     {
00348       BaseName = str.substr(0,p);
00349     }
00350   }
00351 
00352   void GetDirectoryOfThisStringPath( const std::string str, std::string &Directory )
00353   {
00354     std::string::size_type p = 0;
00355     p = str.find_last_of( "\\//" );
00356     if( p == std::string::npos )
00357     {
00358       Directory.erase();
00359     }
00360     else
00361     {
00362       if( p+1 < str.length() )
00363         Directory = str.substr( 0, p+1 );
00364       else
00365         Directory = str;
00366     }
00367   }
00368 
00369   void GetFileNameFromThisStringPath( const std::string str, std::string &FileName )
00370   {
00371     std::string::size_type p = 0;
00372     p = str.find_last_of( "\\//" );
00373     if( p == std::string::npos )
00374     {
00375       FileName = str;
00376     }
00377     else
00378     {
00379       if( p+1 < str.length() )
00380         FileName = str.substr(p+1);
00381       else
00382         FileName = str;
00383     }
00384   }
00385 
00386 } // end of namespace StdStringUtils 
00387