Trimming C++ strings

Posted in Uncategorized by tux4life on July 26, 2009

The c++ string class is one of the most complete implementation of the string library and has functions for every possible string operation one can think of.  But one of the most dearly missed function is the trim() function (to remove the leading and trailing spaces/tabs).

Fortunately, it is very easy to implement an efficient version  the trim function using other member functions of the string class.  This is illustrated in the code snippet shown below.

void trim(std::string& str)
{
std::string trim_chars = ” \t”;
std::string::size_type pos = str.find_last_not_of(trim_chars);
if(pos != std::string::npos) {
str.erase(pos + 1);
pos = str.find_first_not_of(trim_chars);
if(pos != std::string::npos) str.erase(0, pos);
}
else
str.erase(str.begin(), str.end());
}

The logic is pretty simple.  Find the first/last character that is not a space/tab, then remove everything that precedes/follows it.  The else clause handles the case where the string only has spaces or tabs and erases everything.

As a small optimisation, the “trim_chars” variable can be made static so that it is not created and deleted every time the function is called.  This would be particularly helpful if the function called multiple times.

void trim(std::string& str)

{

std::string trim_chars = ” \t”;

std::string::size_type pos = str.find_last_not_of(trim_chars);

if(pos != std::string::npos) {

str.erase(pos + 1);

pos = str.find_first_not_of(trim_chars);

if(pos != std::string::npos) str.erase(0, pos);

}

else

str.erase(str.begin(), str.end());

}

Singleton Pattern

Posted in Programming by tux4life on July 19, 2009

Using design patterns is a very effective way of making the code look neat, robust, reduce maintenance overhead.  Apart from these obvious advantages, design patterns also help convey certain special meaning and restrict programmers from doing things that they are not supposed to do.

For example consider a case where your application needs a Logger.  One can always write a Logger class but ideally you would want only one instance of the Logger class throughout your application.  This restriction can be forced by using the singleton pattern.  The following piece of code illustrates a singleton Logger class.

class Logger {
public:

// The only way to get a reference for the logger class
// is to use the Instance() method
static Logger& Instance() {
static Logger theLog;
return theLog;
}

//     Expose the public methods of the Logger class here
//     void Write(char const *logline);
//     bool SaveTo(char const *filename);
private:
// Hide the constructor
Logger();

// Hide the copy constructor
Logger(Logger const&);

// Hide the assignment operator
Logger& operator=(Logger const&);
};

In the above implementation of the singleton pattern, the default constructor, copy constructor and the assignment operator are hidden.

You can also notice a static instance of the Logger class ‘theLog’ inside the Instance() function.  This function can be used to get a reference for the instance of the Logger class. The one and only instance of the Logger class is created when the Instance() method is called for the first time.  Creation of further instances are restricted as the constructor is hidden and the Instance() function returns a reference to a already created object.  And more over as there is no dynamic memory used, no explicit de-allocations are required.

To summarise, for creating the singleton object,

  1. Hide the default constructor
  2. Hide the copy constructor
  3. Hide the assignment operator
  4. Declare a public static method that returns a reference to a static instance of the class

Finding elements in a STL multimap

Posted in Programming by tux4life on June 24, 2009

Working more and more with STL is helping me learn some subtle nuances of STL.  One such nuance that I learnt today was how to search for an element in a multimap.

Trust me, this slightly more complicated than just using the find method.  Yes, the find method returns an iterator to the matching element.  But remember, this is a multimap.  So, what if there is more than one element with the same key.

We would ideally want to retrieve all the elements with the search key.  But what “find” method does not give is an iterator to the end position to the last instance of the matching key.  So, if you loop through till end of the map, you will go through the matched elements and also the elements that follow the matched elements till the last element in the map.

Fortunately, STL provides a method “equals_range” to get ONLY the items that match the key.  Usage of this function is illustrated below.

Code

#include <iostream>
#include <map>

typedef std::multimap<int, std::string> IntToStringMap;
typedef std::pair<int, std::string> IntStrPair;

int main()
{
IntToStringMap theMap;

//Add elements into the map by constructing pairs
theMap.insert( IntStrPair(1, “ONE”) );
theMap.insert( IntStrPair(3, “THREE”) );
theMap.insert( IntStrPair(2, “TWO”) );
theMap.insert( IntStrPair(2, “ANOTHER TWO”) );
theMap.insert( IntStrPair(2, “YET ANOTHER TWO!”) );

//Use the equal_range function to get a pair of iterators
//pair.first has the iterator pointing to the first key match
//pair.second has the iterator pointing to the last element with matching key
std::pair<IntToStringMap::iterator, IntToStringMap::iterator> itrPair =
theMap.equal_range(2);

IntToStringMap::const_iterator itr = itrPair.first;
if ( itr == theMap.end() ) {
//Search key not found
std::cout<<“Element Not Found”<<std::endl;
}
else {
//Search key found, perhaps more than once
//Loop through till the last match
for ( ; itr != itrPair.second; ++itr)
std::cout << itr->first << “–>” << itr->second << std::endl;
}

return 0;
}

Output

2–>TWO
2–>ANOTHER TWO
2–>YET ANOTHER TWO!

As explained in the comments, the equal_range function returns a pair of iterators.  The first pointing to the first instance of the match and the second pointing to the last instance of the match.  We can use these iterators to loop through our matches.

If there are better solutions for this, please let me know.

Tagged with: , , ,