Thread: Case insensitive string compare...?

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545

    Case insensitive string compare...?

    Hi,
    In Item 35 of "Effective STL", Scott Meyers says to "Implement simple case-insensitive string comparisons via mismatch or lexicographical_compare".

    I can see how the mismatch version would work, but when I tried creating a string comparison function with lexicographical_compare(), it isn't working because lexicographical_compare() only returns true "if the range of elements [start1,end1) is lexicographically less than the range of elements [start2,end2)".

    I tried adding a not2() around the predicate, but that didn't help.

    I have almost the same code as the book (except I'm using the C++ tolower() function)...
    Code:
    	/** ToLowerChar
    	 *  This is a functor that wraps the std::tolower() function.
    	 */
    	template <typename E>
    	class ToLowerChar	:	public std::binary_function<E, std::locale, E>
    	{
    	public:
    		/** ToLowerChar()
    		 *  A constructor for the ToLowerChar functor that sets the Locale to use when converting
    		 *  the characters to lower-case.
    		 *
    		 *  @param loc [IN] - The locale to use for character conversions.
    		 */
    		ToLowerChar( const std::locale&  loc = std::locale() )
    		:	m_Locale( loc ) {}
    
    		/** operator()
    		 *  This operator will return a lower-case version of the character passed to it.
    		 *
    		 *  @param ch [IN] - This is the character to convert to lower-case.
    		 *
    		 *  @param loc [IN] - (optional) This is the locale to use.
    		 *
    		 *  @return E - The lower-case version of the character that was passed in.
    		 */
    		E operator()( E  ch ) const
    		{
    			return std::tolower( ch, m_Locale );
    		}
    
    	private:
    		const std::locale&	m_Locale;	/**< This is the locale to use for character conversions. */
    	};
    
    	/** CharLessNoCase
    	 *  A functor to compare 2 characters without regard to case.
    	 */
    	template <typename E>
    	class CharLessNoCase	:	public std::binary_function<E, E, bool>
    	{
    	public:
    		/** CharLessNoCase()
    		 *  A constructor for the CharLessNoCase functor that sets the Locale to use when converting
    		 *  the characters to lower-case.
    		 *
    		 *  @param loc [IN] - The locale to use for character conversions.
    		 */
    		CharLessNoCase( const std::locale&  loc = std::locale() )
    		:	m_Locale( loc ) {}
    
    		/** operator()
    		 *  First converts both characters to lower-case, then returns true if they
    		 *  are the same or false if they're not.
    		 *
    		 *  @param c1 [IN] - The first character to compare.
    		 *
    		 *  @param c2 [IN] - The second character to compare.
    		 *
    		 *  @return bool - true if the characters are the same (ignoring case),
    		 *			otherwise false if they're different.
    		 */
    		bool operator()( E  c1, E  c2 ) const
    		{
    			return (ToLowerChar<E>( m_Locale )( c1 ) < ToLowerChar<E>( m_Locale )( c2 ));
    		}
    
    	private:
    		const std::locale&	m_Locale;	/**< This is the locale to use for character conversions. */
    	};
    
    	/** StringCompareNoCase
    	 *  This functor compares 2 STL strings without regard to case.
    	 */
    	template <typename E,
    			  typename T = std::char_traits<E>,
    			  typename A = std::allocator<E> >
    	class StringCompareNoCase	:	public std::binary_function<const std::basic_string<E, T, A>&,
    									    const std::basic_string<E, T, A>&,
    									    bool>
    	{
    	public:
    		/** StringCompareNoCase()
    		 *  A constructor for the StringCompareNoCase functor that sets the Locale to use when converting
    		 *  the characters to lower-case.
    		 *
    		 *  @param loc [IN] - The locale to use for character conversions.
    		 */
    		StringCompareNoCase( const std::locale&  loc = std::locale() )
    		:	m_Locale( loc ) {}
    
    		/** operator()
    		 *  Compares 2 STL strings without regard to case.
    		 *
    		 *  @param str1 [IN] - The first string to compare.
    		 *
    		 *  @param str2 [IN] - The second string to compare.
    		 *
    		 *  @return bool - true if the strings are the same (ignoring case),
    		 *			otherwise false if they're different.
    		 */
    		bool operator()( const std::basic_string<E, T, A>&  str1,
    						 const std::basic_string<E, T, A>&  str2 ) const
    		{
    			return std::lexicographical_compare( str1.begin(), str1.end(),
    							     str2.begin(), str2.end(),
    							     CharLessNoCase<E>( m_Locale ) );
    		}
    
    	private:
    		const std::locale&	m_Locale;	/**< This is the locale to use for character conversions. */
    	};
    Am I doing something wrong, or did I completely misunderstand what Scott was talking about?
    Last edited by cpjust; 02-20-2008 at 03:45 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 03-05-2009, 11:32 AM
  2. Inheritance Hierarchy for a Package class
    By twickre in forum C++ Programming
    Replies: 7
    Last Post: 12-08-2007, 04:13 PM
  3. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  4. lvp string...
    By Magma in forum C++ Programming
    Replies: 4
    Last Post: 02-27-2003, 12:03 AM
  5. Changing bkgrnd color of Child windows
    By cMADsc in forum Windows Programming
    Replies: 11
    Last Post: 09-10-2002, 11:21 PM