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.