How can I perform a case insensitive comparison/search of a string?
I want to use cin to have the user input some string and then compare that to what is stored in an array of a string data type. The search/comparison must be case insensitive. Is there any easy way of doing this? I was searching various C++ forums and the process seemed extremely difficult (atleast to me) Haha!
Here is the function that is supposed to do this but it is obviously case sensitive in this format. :(
Please help me out!
#include <iostream>
#include <cctype>
#include <string>
std::string to_lower( std::string str ) // return string with all alpha characters in lower case
{
for( char& c : str ) c = std::tolower(c) ;
return str ;
}
// return -1 if not found
int do_find( const std::string& find_this, const std::string TradeName[], int sz )
{
for( int i = 0 ; i < sz ; ++i )
if( to_lower(find_this) == to_lower( TradeName[i] ) ) return i ;
return -1 ; // not found
}
int findStock( const std::string TradeName[], int sz ) // return -1 if not found
{
std::string symbol ;
std::cout << "Enter the symbol: ";
std::cin >> symbol;
return do_find( symbol, TradeName, sz ) ;
// this function should not be making a unilateral decision
// to exit from the program if the item is not found
// let the caller decide what is to be done if -1 is returned
}
Thank you for your input. Is there anyway to simplify the process of insensitivity? Or is this what I should consider using? Could you explain your code a little more?
I'll just describe what I do, and it looks like JLBorges does pretty much the same above...
Copy your input string and the comparison string and turn the copies to lower-case. Then compare both lower-case only strings to each other. This way you don't have to worry about comparing an upper-case against a lower-case since everything is lower-case.
In line 7 JLBorges is using the std version of tolower(char) to quickly convert the string in a single-line for-each loop and then returns the copy for the comparison in line 15.
You could write your own tolower function for chars as well, but generally the c++ library has optimized code under the hood. Include the cctype library to gain access to the tolower(char) function.
Personally I would write my function to simply compare one string against another instead of testing against an entire array of strings just because it has more utility. I would leave the loop of checks against the array to either main or in this case to findStock(), but that's a personal choice.
>> JLBorges makes a very good point that the choice to exit should be dealt with in main or otherwise the calling function since in the calling function you have a bigger picture of things. Not finding the string usually isn't a reason to exit with an error code (returning a negative number is a good option since an array can't have less than 0 members). http://stackoverflow.com/questions/14109358/correct-usage-of-exit-in-c
> I don't really understand the line that has the for loop. That whole statement line 7.
for( char& c : str ) is a range based loop. http://www.stroustrup.com/C++11FAQ.html#for
It can be read as: for each character c in the string str
We use a reference char& because we want to modify the character in the body of the loop.
std::tolower(c)http://en.cppreference.com/w/cpp/string/byte/tolower
is used to convert c to a lower case character (if it is an upper case character). c = std::tolower(c) leaves c unchanged if it is not an upper case character;
otherwise it replaces c with the equivalent lower case character.