#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <functional>
using namespace std;
#define SPACES " \t\r\n"
inline string trim_right (const string & s, const string & t = SPACES)
  { 
  string d (s); 
  string::size_type i (d.find_last_not_of (t));
  if (i == string::npos)
    return "";
  else
   return d.erase (d.find_last_not_of (t) + 1) ; 
  }  // end of trim_right
inline string trim_left (const string & s, const string & t = SPACES) 
  { 
  string d (s); 
  return d.erase (0, s.find_first_not_of (t)) ; 
  }  // end of trim_left
inline string trim (const string & s, const string & t = SPACES)
  { 
  string d (s); 
  return trim_left (trim_right (d, t), t) ; 
  }  // end of trim
// returns a lower case version of the string 
string tolower (const string & s)
  {
string d (s);
  transform (d.begin (), d.end (), d.begin (), (int(*)(int)) tolower);
  return d;
  }  // end of tolower
// returns an upper case version of the string 
string toupper (const string & s)
  {
string d (s);
  transform (d.begin (), d.end (), d.begin (), (int(*)(int)) toupper);
  return d;
  }   // end of toupper
// transformation function for tocapitals that has a "state"
// so it can capitalise a sequence
class fCapitals : public unary_function<char,char> 
  {
  bool bUpper;
  public:
  // first letter in string will be in capitals
  fCapitals () : bUpper (true) {}; // constructor
  char operator() (const char & c)  
    { 
    char c1;
    // capitalise depending on previous letter
    if (bUpper)
      c1 = toupper (c);
    else
      c1 = tolower (c);
    // work out whether next letter should be capitals
    bUpper = isalnum (c) == 0;
    return c1; 
    }
  };  // end of class fCapitals
// returns a capitalized version of the string 
string tocapitals (const string & s)
  {
string d (s);
  transform (d.begin (), d.end (), d.begin (), fCapitals ());
  return d;
  }  // end of tocapitals
// split a line into the first word, and rest-of-the-line
string GetWord (string & s, 
                const string delim = " ",
                const bool trim_spaces = true)
  {
    
  // find delimiter  
  string::size_type i (s.find (delim));
  // split into before and after delimiter
  string w (s.substr (0, i));
  // if no delimiter, remainder is empty
  if (i == string::npos)
    s.erase ();
  else
    // erase up to the delimiter
    s.erase (0, i + delim.size ());
  // trim spaces if required
  if (trim_spaces)
    {
    w = trim (w);
    s = trim (s);
    }
  // return first word in line
  return w;
  
  } // end of GetWord	
// To be symmetric, we assume an empty string (after trimming spaces)
// will give an empty vector.
// However, a non-empty string (with no delimiter) will give one item
// After that, you get an item per delimiter, plus 1.
// eg.  ""      => empty
//      "a"     => 1 item
//      "a,b"   => 2 items
//      "a,b,"  => 3 items (last one empty)
void StringToVector (const string s, 
                     vector<string> & v,
                     const string delim = " ", 
                     const bool trim_spaces = true)
  {
  // start with initial string, trimmed of leading/trailing spaces if required
  string s1 (trim_spaces ? trim (s) : s);
  v.clear (); // ensure vector empty
  // no string? no elements
  if (s1.empty ())
    return;
  // add to vector while we have a delimiter
  while (!s1.empty () && s1.find (delim) != string::npos)
    v.push_back (GetWord (s1, delim, trim_spaces));
  // add final element
  v.push_back (s1);
  } // end of StringToVector 
// Takes a vector of strings and converts it to a string 
// like "apples,peaches,pears" 
// Should be symmetric with StringToVector (excepting any spaces that might have
//  been trimmed).
string VectorToString (const vector<string> & v, 
                       const string delim = " ")
  {
  // vector empty gives empty string
  if (v.empty ())
    return "";
  // for copying results into
  ostringstream os;
  // copy all but last one, with delimiter after each one
  copy (v.begin (), v.end () - 1, 
        ostream_iterator<string> (os, delim.c_str ()));
  // return string with final element appended
  return os.str () + *(v.end () - 1);
  } // end of VectorToString
int main (void)
  {
  string s ("  happy/days/ are /here/again////  ");                         
  vector<string> v;
  StringToVector (s, v, "/");
  // display item count
  cout << "Converted string into " << v.size () << " items." << endl;
  // convert back into string
  cout << "Vector back to string = (" 
       << VectorToString (v, ", ") << ")" << endl;
  // test other routines
  cout << "original             -->" << s                 << "<--" << endl;
  cout << "trim_right           -->" << trim_right (s)    << "<--" << endl;
  cout << "trim_left            -->" << trim_left (s)     << "<--" << endl;
  cout << "trim                 -->" << trim (s)          << "<--" << endl;
  cout << "tolower              -->" << tolower (s)       << "<--" << endl;
  cout << "toupper              -->" << toupper (s)       << "<--" << endl;
  cout << "tocapitals           -->" << tocapitals (s)    << "<--" << endl;
  cout << "GetWord              -->" << GetWord (s, "/")  << "<--" << endl;
  cout << "After GetWord, s =   -->" << s                 << "<--" << endl;
  return 0;
  } // end of main
Output
Converted string into 9 items.
Vector back to string = (happy, days, are, here, again, , , , )
original             -->  happy/days/ are /here/again////  <--
trim_right           -->  happy/days/ are /here/again////<--
trim_left            -->happy/days/ are /here/again////  <--
trim                 -->happy/days/ are /here/again////<--
tolower              -->  happy/days/ are /here/again////  <--
toupper              -->  HAPPY/DAYS/ ARE /HERE/AGAIN////  <--
tocapitals           -->  Happy/Days/ Are /Here/Again////  <--
GetWord              -->happy<--
After GetWord, s =   -->days/ are /here/again////<--
#include <string>
#include <iostream>
#include <functional>
using namespace std;  
// case-independent (ci) string compare
// returns true if strings are EQUAL
struct ci_equal_to : binary_function <string, string, bool>
  {
  struct compare_equal 
    : public binary_function <unsigned char, unsigned char,bool>
    {
    bool operator() (const unsigned char& c1, const unsigned char& c2) const
      { return tolower (c1) == tolower (c2); }
    };  // end of compare_equal
  bool operator() (const string & s1, const string & s2) const
    {
    pair <string::const_iterator,
          string::const_iterator> result =
      mismatch (s1.begin (), s1.end (),   // source range
                s2.begin (),              // comparison start
                compare_equal ());  // comparison
    // match if both at end
    return result.first == s1.end () &&
           result.second == s2.end ();
    }
  }; // end of ci_equal_to
// compare strings for equality using the binary function above
// returns true is s1 == s2
bool ciStringEqual (const string & s1, const string & s2)
  {
  return ci_equal_to () (s1, s2);
  }  // end of ciStringEqual
// case-independent (ci) string less_than
// returns true if s1 < s2
struct ci_less : binary_function <string, string, bool>
  {
  // case-independent (ci) compare_less binary function
  struct compare_less 
    : public binary_function <unsigned char, unsigned char,bool>
    {
    bool operator() (const unsigned char& c1, const unsigned char& c2) const
      { return tolower (c1) < tolower (c2); }
    }; // end of compare_less
  bool operator() (const string & s1, const string & s2) const
    {
    return lexicographical_compare
          (s1.begin (), s1.end (),   // source range
           s2.begin (), s2.end (),   // dest range
                  compare_less ());  // comparison
    }
  }; // end of ci_less
// compare strings for less-than using the binary function above
// returns true if s1 < s2
bool ciStringLess (const string & s1, const string & s2)
  {
  return ci_less () (s1, s2);
  }  // end of ciStringLess
// compare to see if start of s1 is s2
//  eg. returns true for: strPrefix ("abacus", "aba");
bool strPrefix (const string & s1,             // string to search    
                const string & s2,             // what to look for 
                const bool no_case = false)    // case-insensitive?   
  {                                               
  
  // if either string is empty or s1 is smaller than s2
  //  then they can't be identical
  if (s1.empty () ||
      s2.empty () ||
      s1.size () < s2.size ())
    return false;
  if (no_case)
    return ciStringEqual (s1.substr (0, s2.size ()), s2);
  else
    return s1.substr (0, s2.size ()) == s2;
  } // end of strPrefix
// compares to see if (s1, offset by pos, for length s2) == s2
bool strPrefix (const string & s1,              // string to search
                const string::size_type pos,    // where in s1 to start
                const string & s2,              // what to look for
                const bool no_case = false)     // case-insensitive?
  {
  // can't be true if position outside string size
  // casts are to ensure a signed comparison 
  if ((int) pos >= ((int) s1.size () - (int) s2.size ()))
    return false;
  // make a substring of s1 for s2's size
  return strPrefix (s1.substr (pos, s2.size ()), s2, no_case);
  } // end of strPrefix
// test
int main (void)
  {
  cout << boolalpha;
  cout << "Should be true ..." << endl << endl;
  // these should be true
  cout << "Nick == nick = "           << ciStringEqual ("Nick", "nick") << endl;
  cout << "Nick >= nick = "           << !ciStringLess ("Nick", "nick") << endl;
  cout << "Nick prefix == Ni = "      << strPrefix ("Nick", "Ni") << endl;
  cout << "Nick ci_prefix == ni = "   << strPrefix ("Nick", "ni", true) << endl;
  cout << "AABBC prefix (2) == BB = " << strPrefix ("AABBC", 2, "BB") << endl;
  cout << endl << "Should be false ..." << endl << endl;
  // these should be false
  cout << "Nick == nicky = "          << ciStringEqual ("Nick", "nicky") << endl;
  cout << "Nick < aaaa = "            << ciStringLess ("Nick", "aaaa") << endl;
  cout << "Nick prefix == ni = "      << strPrefix ("Nick", "ni") << endl;
  cout << "Nack ci prefix == ni = "   << strPrefix ("Nack", "ni", true) << endl;
  cout << "AABBC prefix (3) == BB = " << strPrefix ("AABBC", 3, "BB") << endl;
  return 0;
  } // end of main
Output
Should be true ...
Nick == nick = true
Nick 
>= nick = true
Nick prefix == Ni = true
Nick ci_prefix == ni = 
true
AABBC prefix (2) == BB = true
Should be false ...
Nick == 
nicky = false
Nick < aaaa = false
Nick prefix == ni = false
Nack ci 
prefix == ni = false
AABBC prefix (3) == BB = false