question about string compare stricmp

X

xuatla

Hi,

I want to compare two strings regardless of the lowercase or uppercase.
For example, "txt" same as "TXT", "Txt", ...

I know that there's stricmp in some c++ that can perform a lowercase
comparison. But when I use <cstring>, I can't find such function. Do you
know any other standard c++ function(s) can do this task?

Thanks,
X
 
R

red floyd

xuatla said:
Hi,

I want to compare two strings regardless of the lowercase or uppercase.
For example, "txt" same as "TXT", "Txt", ...

I know that there's stricmp in some c++ that can perform a lowercase
comparison. But when I use <cstring>, I can't find such function. Do you
know any other standard c++ function(s) can do this task?

Thanks,
X

I think you have to roll your own.
 
M

mahurshi

how about using c_str() first and then using strcmp?
http://www.cppreference.com/cppstring/c_str.html

i quickly wrote something to test this myelf (hopefully this is the
correct way to do this):

#include <iostream>
#include <string>

using namespace std;

int main()
{
string test1 = "abcd";
string test2 = "AbCd";

cout << test1 << " " << test2 << " " << strcmp(test1.c_str(),
test2.c_str()) << endl;

test2 = "ABCD";

cout << test1 << " " << test2 << " " << strcmp(test1.c_str(),
test2.c_str()) << endl;

test2 = "abcd";


cout << test1 << " " << test2 << " " << strcmp(test1.c_str(),
test2.c_str()) << endl;

test2 = "dcba";

cout << test1 << " " << test2 << " " << strcmp(test1.c_str(),
test2.c_str()) << endl;

test2 = "abcdE";

cout << test1 << " " << test2 << " " << strcmp(test1.c_str(),
test2.c_str()) << endl;

return 0;
}

output
----------------------
abcd AbCd 1
abcd ABCD 1
abcd abcd 0
abcd dcba -1
abcd abcdE -1
 
K

Kai-Uwe Bux

xuatla said:
Hi,

I want to compare two strings regardless of the lowercase or uppercase.
For example, "txt" same as "TXT", "Txt", ...

I know that there's stricmp in some c++ that can perform a lowercase
comparison. But when I use <cstring>, I can't find such function. Do you
know any other standard c++ function(s) can do this task?

Thanks,
X

Such comparisons depend on your locale. The following code defaults to the
global locale std::locale().

#include <locale>
#include <string>
#include <iostream>

template < typename CharIter >
bool
sequence_equal_to_ignoring_case ( CharIter a_from, CharIter a_to,
CharIter b_from, CharIter b_to,
std::locale const & loc = std::locale() ) {
if ( std::distance( a_from, a_to )
!=
std::distance( b_from, b_to ) ) {
return ( false );
}
for ( CharIter a_iter = a_from, b_iter = b_from;
a_iter != a_to;
++ a_iter, ++b_iter ) {
if ( std::tolower( *a_iter, loc ) != std::tolower( *b_iter, loc ) ) {
return ( false );
}
}
return ( true );
}

bool
string_equal_to_ignoring_case ( std::string const & a,
std::string const & b,
std::locale const & loc = std::locale() ) {
return( sequence_equal_to_ignoring_case( a.begin(), a.end(),
b.begin(), b.end(),
loc ) );
}

int main ( void ) {
std::string a ( "Hello World!" );
std::string b ( "hello world!" );
std::cout << string_equal_to_ignoring_case( a, b ) << '\n';
}


Best

Kai-Uwe Bux

ps.: Isn't this in the FAQ? and should it be in the FAQ?
 
X

xuatla

Thank you.

Yes for functions related with char * I use .c_str().
But strcmp is case sensative.

For example, comparing abcd AbCC also gives result 1. So this function
is not good for case insensative comparison.

I am also looking for "standard" functions as makeupper() or makelower()
in CString in MFC. It seems that we don't have such functions in
standard C++ library.

Regards,
X
 
?

=?ISO-8859-1?Q?Stefan_N=E4we?=

Kai-Uwe Bux said:
Such comparisons depend on your locale. The following code defaults to the
global locale std::locale().

#include <locale>
#include <string>
#include <iostream>

template < typename CharIter >
bool
sequence_equal_to_ignoring_case ( CharIter a_from, CharIter a_to,
CharIter b_from, CharIter b_to,
std::locale const & loc = std::locale() ) {
if ( std::distance( a_from, a_to )
!=
std::distance( b_from, b_to ) ) {
return ( false );
}
for ( CharIter a_iter = a_from, b_iter = b_from;
a_iter != a_to;
++ a_iter, ++b_iter ) {
if ( std::tolower( *a_iter, loc ) != std::tolower( *b_iter, loc ) ) {
return ( false );
}
}
return ( true );
}

bool
string_equal_to_ignoring_case ( std::string const & a,
std::string const & b,
std::locale const & loc = std::locale() ) {
return( sequence_equal_to_ignoring_case( a.begin(), a.end(),
b.begin(), b.end(),
loc ) );
}

int main ( void ) {
std::string a ( "Hello World!" );
std::string b ( "hello world!" );
std::cout << string_equal_to_ignoring_case( a, b ) << '\n';
}

Any problems with this solution ??


bool
char_equal_icase(char a, char b, std::locale const & loc = std::locale() )
{
return ( std::tolower( a, loc ) ==
std::tolower( b, loc ) );
}

bool
string_equal_icase ( std::string const & a,
std::string const & b,
std::locale const & loc = std::locale() )
{
return ((a.size() == b.size()) &&
(std::mismatch(a.begin(), a.end(), b.begin(), char_equal_icase).first == a.end()));
}


Stefan
 
?

=?ISO-8859-1?Q?Stefan_N=E4we?=

Stefan said:
Any problems with this solution ??

Yes!
The locale doesn'T get passed to char_equal_icase().
bool
char_equal_icase(char a, char b, std::locale const & loc = std::locale() )
{
return ( std::tolower( a, loc ) ==
std::tolower( b, loc ) );
}

bool
string_equal_icase ( std::string const & a,
std::string const & b,
std::locale const & loc = std::locale() )
{
return ((a.size() == b.size()) &&
(std::mismatch(a.begin(), a.end(), b.begin(), char_equal_icase).first == a.end()));
}

Better:


struct char_equal_icase
{
char_equal_icase(std::locale const & loc = std::locale())
: loc_(loc)
{
}

bool
operator()(char a, char b )
{
return ( std::tolower( a, loc_ ) == std::tolower( b, loc_) );
}

private:
std::locale const & loc_;
};

bool
string_equal_icase ( std::string const & a,
std::string const & b,
std::locale const & loc = std::locale() )
{
return ((a.size() == b.size()) &&
(std::mismatch(a.begin(), a.end(), b.begin(), char_equal_icase(loc)).first == a.end()));
}



Stefan
 
M

Maxim Yegorushkin

xuatla said:
Hi,

I want to compare two strings regardless of the lowercase or uppercase.
For example, "txt" same as "TXT", "Txt", ...

I know that there's stricmp in some c++ that can perform a lowercase
comparison. But when I use <cstring>, I can't find such function. Do you
know any other standard c++ function(s) can do this task?

There is none.

You can use Apache Portable Runtime for that:
http://apr.apache.org/docs/apr/group__apr__strings.html#ga1
 
R

Robbie Hatley

xuatla said:
I want to compare two strings regardless of ... case ...


Here's my solution that I use whenever I want non-case compare:


// Determine whether two std::strings are non-case-sensitively "equal":
inline bool NCS_Equal (std::string const & Bob, std::string const & Fred)
{
return StringToLower(Bob) == StringToLower(Fred);
}

// Convert string to all-lower-case:
std::string StringToLower (std::string const & InputString)
{
std::string OutputString;
std::string::const_iterator i;
for (i = InputString.begin(); i != InputString.end(); ++i)
{
if (isupper(*i)) OutputString.push_back(tolower(*i));
else OutputString.push_back(*i);
}
return OutputString;
}


Doesn't deal with locales. May possibly fail in some countries.
But works fine for English language and ASCII encoding, which are
all that many programmers deal with.


Cheers,
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top