Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

toddburch

macrumors 6502a
Original poster
Dec 4, 2006
748
0
Katy, Texas
I've looked in an online reference (cppreference.com) and my C++ book, but I can't find a string insensitive compare(). There are certainly C-String case insensitive compares, but I'd rather use a C++ compare if there is one.

(Plus, now I'm on a mission to find it...)

Thanks, Todd
 

toddburch

macrumors 6502a
Original poster
Dec 4, 2006
748
0
Katy, Texas
I guess I could use a bitset OR with a known longer-than-I-needed string of all blanks (X'20') and then test for a lower case compare...
 

iSee

macrumors 68040
Oct 25, 2004
3,539
272
It's almost beyond belief, but I don't believe the standard C++ library has a case-insensetive.

If you don't want or need to worry about locales, then:
_stricmp( str1.c_str(), str2.c_str() )
Is the simplest solution (also quite efficient).

Locales complicate things quite a bit (well, it's really the deficiencies of the standard library that makes this so complicated).
Lemme see if I can find a link for something that deals with locales...
here's one: http://lafstern.org/matt/col2_new.pdf
I don't know if he really knows what he's talking about, but it sounds like he does. He goes on for a while about this so you can understand the issue, but you can skip to the bottom and check out the last code block for his best solution.
 

toddburch

macrumors 6502a
Original poster
Dec 4, 2006
748
0
Katy, Texas
Thanks iSee. Yeah, he's probably correct. However, for my purposes, I'll be working with 7-bit ASCII character codes, and I think this code chunk will be good enough.

Thanks for the confirmation - glad to see I wasn't just missing it.

Todd

Code:
#include <iostream>
#include <string> 
using namespace std ; 

bool case_insensitive_compare( string a, string b) { 
	char char1, char2, blank = ' ' ;   
	int len1 = a.length() ; 
	int len2 = b.length() ;  

	for (int i = 0 ; i < min(len1, len2) ; ++i ) { 
		char1 = *(a.substr(i,1).data()) ;   // get a single character
		char2 = *(b.substr(i,1).data()) ; 
		char1 |= blank ;   // make lowercase for compare 
		char2 |= blank ; 
		if ( char1 == char2 ) continue ; 
		return false ; 
	} 
	if (len1 != len2) return false ; 
	return true ; 
} 

int main (int argc, char * const argv[]) {
	string input ; 
	string hello = "Hello" ; 
	bool result ; 
	
	std::cout << "Enter the word 'hello', in any form of upper or lower case characters." << endl ; 
	std::cin >> input ; 
	
	result = case_insensitive_compare(input, hello) ; 

    std::cout << "Result of compare of " << input << " to " << hello << " is " << (result ? "true" : "false" )  << endl ;
    return 0;
}
 

iSee

macrumors 68040
Oct 25, 2004
3,539
272
OK, I give up. Where did you come up with _stricmp?

Todd

OK, sorry for throwing that out there.

I thought it was part of the standard C library, but it isn't. It just appears, unofficially, under different names, in various implementations of the C library. So a case-insensitive compare isn't an official part of the official C library either. Geeze. It seems like such a huge omission. Under VS, it's _stricmp() or stricmp(), under CodeWarrior for Mac it's stricmp() or strcasecmp(), and under OS X 10.4/Xcode it's strcasecmp().

Come to think of it, the leading underscore should have given me the hint.

I guess if you want to conform to the C standard you have to implement your own using tolower() (or toupper()) in a loop.

Let's see a first pass might be (This is off the top of my head, NOT tested code):
Code:
#include <ctype.h>
...
int mystricmp(const char* str1, const char* str2)
{
  if (str1 == str2)
    return 0;
  else if (str1 == NULL)
    return -1;
  else if (str2 == NULL)
    return 1;
  else {
    while (tolower(*str1) == tolower(*str2) && *str1 != 0 && *str2 != 0)
    {
      ++str1;
      ++str2;
    }
    if (*str1 < *str2)
      return -1;
    else if (*str1 > *str2)
      return 1;
    else
      return 0;
  }
}

Anyway, again, sorry for the bad advice. I guess I haven't really done a lot of C/C++ coding on Mac OS X where I wanted to avoid the OS API (CFString, etc.) since the CodeWarrior days...
 

toddburch

macrumors 6502a
Original poster
Dec 4, 2006
748
0
Katy, Texas
Ahhhha. Makes sense. Thanks Wittegijt & iSee. I've been reading my "Encyclopedia C" (Sybex, 1991) and all (or a lot of, at least) the non-standard keywords by Microsoft all have an underscore for the first character as well. Should have tipped me off.

OK, now to strcasecmp(). The cppreference.com web site I've been using looks to be only standard C/C++. I've googled for a Mac OS X XCode specific reference site and haven't found one. What's a good Mac OS X C++ reference website? Or, is there a C++ reference built into XCode help somewhere and I just haven't found it? Or, failing all that, is there one on the Apple Development Center that I've missed too?

As big as the XCode diskimages are that I download and install when prompted, surely there's a language reference in there someone - I mean, the Java stuff I downloaded initially was HUGE.

Todd
 

Krevnik

macrumors 601
Sep 8, 2003
4,100
1,308
OK, now to strcasecmp(). The cppreference.com web site I've been using looks to be only standard C/C++. I've googled for a Mac OS X XCode specific reference site and haven't found one. What's a good Mac OS X C++ reference website? Or, is there a C++ reference built into XCode help somewhere and I just haven't found it? Or, failing all that, is there one on the Apple Development Center that I've missed too?

It is there, but I don't think it goes over the C functions that are in the POSIX layer, just all of Apple's additions to POSIX. You can use the terminal to access man pages on some of these functions. 'man strcasecmp' will take you right to the page talking about that function and describe how to use it.
 

iSee

macrumors 68040
Oct 25, 2004
3,539
272
Poking around in Xcode, I found a link to this page:

http://developer.apple.com/documentation/Darwin/Reference/ManPages/index.html

which is a table of contents for everything in the OS X man pages, including the C library functions.

The Xcode reference library accesses man pages in addition to other resources, so these are all available through Xcode (I use "Find Selected Text in API Reference" all the time).

It looks like the C functions are in section 3. It looks like the documentation for each function contains a "standard" or "history" section that gives some info on what standard the function complies with. Apparently strcasecmp() was moved from "string.h" to "strings.h" for compliance reasons. I'm not sure in exactly what way that makes it compliant. I guess it means that non-standard functions should not appear in string.h, so they moved it to a different header file.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.