Comparing and Searching String Objects

Core Foundation String Services includes a number of functions for searching the contents of strings and for comparing two strings. Because these operations are semantically related, it is not surprising that the main functions for each operation-- CFStringFindWithOptions and CFStringCompareWithOptions --have some things in common. Their first four parameters are almost identical: two references to CFString objects (the strings to be compared or the substring to find in the main string), a range of characters to include in the operation, and a bitfield for specifying options.

But these functions have important differences too. The CFStringCompareWithOptions function returns a result of type CFComparisonResult ; this enum constant indicates whether the comparison found the strings equal or whether the first specified string was greater than or less than the second string. The CFStringFindWithOptions function, on the other hand, returns a Boolean result that indicates the success of the operation. The more useful result, returned indirectly by this function, is a range (a structure of type CFRange ) pointed to by its final parameter; this range contains the location of the found string in the main string.

Listing 11 illustrates the use of both of these methods; it makes use of the show function whose implementation is shown in Listing 4.

Listing 11 Comparing and searching CFString contents
void compareAndSearchStringsExample() { CFStringRef str1 = CFSTR("ABCDEFG"); CFStringRef str2 = CFSTR("abcdefg"); CFStringRef str3 = CFSTR("Kindergarten is the time to start teaching the ABCDEFG's"); CFRange foundRange; CFComparisonResult result; result = CFStringCompareWithOptions(str1, str2, CFRangeMake(0,CFStringGetLength(str1)), kCFCompareCaseInsensitive); if (result == kCFCompareEqualTo) { show(CFSTR("%@ is the same as %@"), str1, str2); } else { show(CFSTR("%@ is not the same as %@"), str1, str2); } if ( CFStringFindWithOptions(str3, str1, CFRangeMake(0,CFStringGetLength(str3)), kCFCompareCaseInsensitive, &foundRange) == true ) { show(CFSTR("The string \"%@\" was found at index %d in string \"%@\"."), str1, foundRange.location, str3); } else { show(CFSTR("The string \"%@\" was not found in string \"%@\"."), str1, str3); } }

This code generates the following output:

 ABCDEFG is the same as abcdefgThe string "ABCDEFG" was found at index 47 in string "Kindergarten is the time to start teaching the ABCDEFG's". 

In this example, both the find and compare functions specify the kCFCompareCaseInsensitive flag as an option for the operation, causing it to ignore differences in case. Other option flags are available, including kCFCompareBackwards (start the operation from the end of the string), kCFCompareNumerically (compare similar strings containing numeric substrings numerically), and kCFCompareLocalized (use the user's default locale for the operation).

The basis for comparison of CFString objects is Unicode equality, which in implementation can be rather complicated. If you want a character-by-character literal comparison, use a search or compare function with the kCFCompareLiteral flag as an option.

In addition to the main compare and find functions, String Services provides some convenience functions. CFStringFind and CFStringCompare are similar to the "main" functions described above but they do not require the specification of a range (the entire string is assumed). Note that you can use CFStringCompare elsewhere in Core Foundation when a function pointer conforming to the CFComparatorFunction type is required.

Other interesting search and comparison functions of String Services are CFStringHasPrefix , CFStringHasSuffix , and CFStringCreateArrayWithFindResults . The last of these functions is useful when you expect multiple hits with a search operation; it returns an array of CFRange structures, each of which specifies the location of a matching substring in the main string.


© 1999 Apple Computer, Inc. – (Last Updated 07 September 99)