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 #ifndef _CRT_SECURE_NO_DEPRECATE
00048 #define _CRT_SECURE_NO_DEPRECATE
00049 #endif
00050 
00051 
00052 
00053 namespace StdStringUtils
00054 {
00055   void SpanExcluding(const std::string &src, const std::string charSet, std::string &dst)
00056   {
00057     std::string::size_type p = 0;
00058     if( src.empty() )
00059       return;
00060 
00061     dst = src;
00062     p = src.find_first_of( charSet );
00063     if( p != std::string::npos )
00064       dst.erase(p);
00065   }
00066 
00067   void SpanExcluding(const std::string &src, const std::string charSet, std::string &dst, std::string::size_type& pos)
00068   {
00069     int index;
00070     std::string::size_type p = 0;
00071     if( src.empty() )
00072       return;
00073 
00074     dst = src;
00075     p = src.find_first_of( charSet );
00076     if( p != std::string::npos )
00077     {
00078       dst.erase(p);
00079       pos = src.find_first_not_of( charSet, p );
00080       index = static_cast<int>(pos-1);
00081       if( index < 0 )
00082       {
00083         pos = 0;
00084       }
00085       else
00086       {
00087         pos = pos-1;
00088       }
00089     }
00090     else
00091     {
00092       pos = std::string::npos;
00093     }
00094   }
00095 
00096 
00097   void SpanNotExcluding(const std::string &src, const std::string charSet, std::string &dst, std::string::size_type& pos)
00098   {
00099     std::string::size_type p = 0;
00100     if( src.empty() )
00101       return;
00102 
00103     dst = src;
00104     p = src.find_first_not_of( charSet );
00105     if( p != std::string::npos )
00106     {
00107       dst.erase(p);
00108       pos = p;
00109     }
00110     else
00111     {
00112       pos = std::string::npos;
00113     }
00114   }
00115 
00116   void MakeUpper(std::string &str)
00117   {
00118     std::transform(str.begin(),str.end(),str.begin(),toupper);
00119   }
00120 
00121   void MakeLower(std::string &str)
00122   {
00123     std::transform(str.begin(),str.end(),str.begin(),tolower);
00124   }
00125 
00126   void TrimRight(std::string &str) 
00127   {
00128     std::string::size_type p = 0;
00129     std::string whitespace = " \t\n\f\r";
00130     p = str.find_last_not_of(whitespace);
00131     if( p != std::string::npos )
00132     {
00133       if( p != str.length()-1 ) // check not at the end of the string
00134         str.erase(p+1);
00135     }
00136     else
00137     {
00138       str.erase();
00139     }
00140   }
00141 
00142   void TrimLeft(std::string &str) 
00143   {
00144     std::string::size_type p = 0;
00145     std::string whitespace = " \t\n\f\r";
00146     p = str.find_first_not_of(whitespace);
00147     if( p != std::string::npos )
00148     {
00149       if( p != 0 )
00150         str = str.substr( p );
00151     }      
00152     else
00153     {
00154       str.erase();
00155     }
00156   }
00157 
00158   void TrimLeftAndRight(std::string &str) 
00159   {
00160     TrimLeft(str);
00161     TrimRight(str);
00162   }
00163 
00164   bool GetDouble( const std::string &str, double &value )
00165   {
00166 #ifndef _CRT_SECURE_NO_DEPRECATE
00167     if( sscanf_s( str.c_str(), "%lf", &value) == 1 )
00168     {
00169       return true;
00170     }
00171     else
00172     {
00173       value = 0;
00174       return false;
00175     }
00176 #else    
00177     if( sscanf( str.c_str(), "%lf", &value) == 1 )
00178     { 
00179       return true;
00180     }
00181     else
00182     {
00183       value = 0;
00184       return false;
00185     }
00186 #endif
00187   }
00188   
00189 
00190   bool GetFloat( const std::string &str, float &value )
00191   {
00192 #ifndef _CRT_SECURE_NO_DEPRECATE
00193     if( sscanf_s( str.c_str(), "%f", &value) == 1 )
00194     {
00195       return true;
00196     }
00197     else
00198     {
00199       value = 0;
00200       return false;
00201     }
00202 #else    
00203     if( sscanf( str.c_str(), "%f", &value) == 1 )
00204     {
00205       return true;
00206     }
00207     else
00208     {
00209       value = 0;
00210       return false;
00211     }
00212 #endif
00213   }
00214 
00215   bool GetInt( const std::string &str, int &value )
00216   {
00217 #ifndef _CRT_SECURE_NO_DEPRECATE
00218     if( sscanf_s( str.c_str(), "%i", &value) == 1 )
00219     {
00220       return true;
00221     }
00222     else
00223     {
00224       value = 0;
00225       return false;
00226     }
00227 #else    
00228     if( sscanf( str.c_str(), "%i", &value) == 1 )
00229     {
00230       return true;
00231     }
00232     else
00233     {
00234       value = 0;
00235       return false;
00236     }
00237 #endif
00238   }
00239 
00240   bool GetUnsignedInt( const std::string &str, unsigned &value )
00241   {
00242 #ifndef _CRT_SECURE_NO_DEPRECATE
00243     if( sscanf_s( str.c_str(), "%u", &value) == 1 )
00244     {
00245       return true;
00246     }
00247     else
00248     {
00249       value = 0;
00250       return false;
00251     }
00252 #else    
00253     if( sscanf( str.c_str(), "%u", &value) == 1 )
00254     {
00255       return true;
00256     }
00257     else
00258     {
00259       value = 0;
00260       return false;
00261     }
00262 #endif
00263   }
00264   
00265   bool ExtractField( const std::string &str, const unsigned index, const char delimiter, std::string &field )
00266   {
00267     unsigned i = 0;
00268     std::string::size_type scount = 0;
00269     std::string DelimiterStr;
00270     std::string ExtractStr;
00271 
00272     if( delimiter == 'w' )
00273     {
00274       DelimiterStr = " \t\r\n\f";
00275     }
00276     else
00277     {
00278       DelimiterStr = delimiter;
00279     }
00280     ExtractStr = str;
00281 
00282     for( i = 0; i <= index; i++ )
00283     {
00284       if( scount >= str.length() )
00285       {
00286         ExtractStr.erase();
00287         field.erase();
00288         break;
00289       }
00290       else
00291       {
00292         ExtractStr = str.substr( scount );
00293       }
00294 
00295       SpanExcluding( ExtractStr, DelimiterStr, field );
00296       scount += field.length() + 1; // plus one for the delimiter
00297       if( field.empty() && ExtractStr.empty() )
00298         break; // no more data      
00299     }
00300     if( !ExtractStr.empty() )
00301     {
00302       return true;
00303     }
00304     else
00305     {
00306       field.erase();
00307       return false;
00308     }
00309   }
00310 
00311   bool ExtractFieldInplace( std::string &str, const char delimiter, std::string &field )
00312   {
00313     std::string DelimiterStr;
00314 
00315     if( delimiter == 'w' )
00316     {
00317       DelimiterStr = " \t\r\n\f";
00318     }
00319     else
00320     {
00321       DelimiterStr = delimiter;
00322     }
00323     if( str.empty() )
00324     {
00325       field.erase();
00326       return false;
00327     }
00328     SpanExcluding( str, DelimiterStr, field );      
00329     if( field.length() < str.length() )
00330       str = str.substr( field.length() + 1 );
00331     else
00332       str.erase();
00333 
00334     if( delimiter == 'w' )
00335     {
00336       TrimLeft(str);
00337     }
00338     return true;
00339   }
00340 
00341   void GetBaseName( const std::string str, std::string &BaseName )
00342   {
00343     std::string::size_type p = 0;
00344     p = str.find_last_of( "." );
00345     if( p == std::string::npos )      
00346     {
00347       BaseName = str;
00348     }
00349     else
00350     {
00351       BaseName = str.substr(0,p);
00352     }
00353   }
00354 
00355   void GetDirectoryOfThisStringPath( const std::string str, std::string &Directory )
00356   {
00357     std::string::size_type p = 0;
00358     p = str.find_last_of( "\\//" );
00359     if( p == std::string::npos )
00360     {
00361       Directory.erase();
00362     }
00363     else
00364     {
00365       if( p+1 < str.length() )
00366         Directory = str.substr( 0, p+1 );
00367       else
00368         Directory = str;
00369     }
00370   }
00371 
00372   void GetFileNameFromThisStringPath( const std::string str, std::string &FileName )
00373   {
00374     std::string::size_type p = 0;
00375     p = str.find_last_of( "\\//" );
00376     if( p == std::string::npos )
00377     {
00378       FileName = str;
00379     }
00380     else
00381     {
00382       if( p+1 < str.length() )
00383         FileName = str.substr(p+1);
00384       else
00385         FileName = str;
00386     }
00387   }
00388 
00389 } // end of namespace StdStringUtils 
00390