Metric Scantlings Metric Scantlings - 5 months ago 14
Objective-C Question

How to check if NSString format contains the same number of specifiers as there are variadic arguments?

To ensure that a formatted string returned by

NSString initWithFormat:arguments:
is as expected, I need to determine if there are the same number of format specifiers as arguments. Below is a (slightly contrived and highly edited) example:

- (void)thingsForStuff:(CustomStuff)stuff, ...
{
NSString *format;
switch (stuff)
{
case CustomStuffTwo:
format = @"Two things: %@ and %@";
break;

case CustomStuffThree:
format = @"Three things: %@, %@, and %@";
break;

default:
format = @"Just one thing: %@";
break;
}

va_list args;
va_start(args, method);
// Want to check if format has the same number of %@s as there are args, but not sure how
NSString *formattedStuff = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);

NSLog(@"Things: %@", formattedStuff);
}


Using this method,
[self thingsForStuff:CustomStuffTwo, @"Hello", @"World"]
would log


"Two things: Hello and World"


...but
[self thingsForStuff:CustomStuffTwo, @"Hello"]
would log


"Two things: Hello and "


...something that would be preferred to be caught before it happens.

Is there a way to count the format specifiers in a string, preferably something lightweight/inexpensive?

Answer

Is there a way to count the format specifiers in a string, preferably something lightweight/inexpensive?

Nope -- really isn't. At least, not if you want it to work across all possible format strings. You would have to duplicate the parser that is used by stringWithFormat:. I.e. don't try to validate everything.

You could count the number of %, but that would not catch things like %% or other special cases. That may be good enough for your purposes.

Comments