Creating String Objects From Formatted Strings

String Services includes functions that create CFString objects from formatted strings--strings incorporating printf -style specifiers for substituting variable values into the string, after converting them (if necessary) to character data. Formatted strings are useful when it is necessary to display information that may have changeable elements. For example, you might need to use these functions when you put up a dialog box to show the progress of an operation, such as "Copying file x of y ."

The CFStringCreateWithFormat function creates a CFString object from a simple formatted string, as shown in Listing 3.

Listing 3 Creating a CFString object from a formatted string
CFStringRef PrintGross(CFStringRef employeeName, UInt8 hours, float wage) { return CFStringCreateWithFormat(NULL, NULL, CFSTR("Employee %@ earned $%.2f this week."), employeeName, hours * wage); }

The first parameter, as usual, specifies the allocator object to use ( NULL means use the default CFAllocator object). The second parameter is for locale-dependent format options, such as thousand and decimal separators; it is currently not used. The remaining parameters are for the format string and the variable values.

As mentioned earlier, the format string has printf -style specifiers embedded in it (for example, "%d %s %2.2f" ). Core Foundation introduces a couple of extensions to this convention. One is the %@ specifier (shown in Listing 3) which indicates any Core Foundation object. Another new specifier indicates argument order. This specifier takes the form n $ where n is the order-number of the argument following the string. This argument-order feature is useful when you want to localize whole sentences or even paragraphs to other languages without worrying about the order of arguments, which might vary from one language to another.

For example, the function above would result in a string such as "John Doe earned $1012.32 this week." But in another language the grammatically proper way of expressing the same sentence might be (roughly translated) "$1012.32 was earned by John Doe this week."You wouldn't have to call CFStringCreateWithFormat again with the arguments in a different order. Instead, you would have a function call that looked like this:

 return CFStringCreateWithFormat(NULL, NULL, CFSTR("$%2$.2f was earned by 
 	employee %1$@."), employeeName, hours * wage); 

Of course, the string itself would not be hard-coded, but would be loaded from a file (for instance, an XML property list) that contains localized strings and their translations.

Another String Services function, CFStringCreateWithFormatAndArguments , takes a variable argument list ( vararg ) as well as a format string. This function allows the formatting of vararg s passed into your function. Listing 4 shows how it might be used:

Listing 4 Creating a CFString from a variable argument list
void show(CFStringRef formatString, ...) { CFStringRef resultString; CFDataRef data; va_list argList; va_start(argList, formatString); resultString = CFStringCreateWithFormatAndArguments(NULL, NULL formatString, argList); va_end(argList); data = CFStringCreateExternalRepresentation(NULL, resultString, CFStringGetSystemEncoding(), '?'); if (data != NULL) { printf ("%.*s\n\n", (int)CFDataGetLength(data), CFDataGetBytePtr(data)); CFRelease(data); } CFRelease(resultString); }

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