willc2
willc2

Reputation: 39671

Is it possible to use format strings to align NSStrings like numbers can be?

I'm using NSLog() to print some tabular data consisting of an NSString and an associated integer.

Assume I know the length of the longest word.

Is there a way using format strings to get this kind of column alignment:

word:tree        rank:5  
word:frog        rank:3  
word:house       rank:2  
word:peppercorn  rank:2  
word:sword       rank:2  
word:antlion     rank:1  

The reason I'm asking about formatting strings is I'm hoping for a lightweight way to format my ghetto debugging output.

Here is what I tried:

NSString *word = @"tree";
NSUInteger rank = 4;
NSString *str = [NSString stringWithFormat:@"word:%-20@ rank:%u", word, rank];
NSLog(@"%@", str);

Result:

word:tree rank:4

No effect at all.

Upvotes: 13

Views: 5912

Answers (3)

rickster
rickster

Reputation: 126117

If you do something like the earlier answer:

NSString *word = @"tree";
NSUInteger rank = 4;
NSString *str = [NSString stringWithFormat:@"word:%-20s rank:%u", [word UTF8String], rank];
NSLog(@"%@", str);

... you can get encoding-conversion problems for non-ASCII characters... stringWithFormat seems to assume the system default encoding, which is still MacRoman for some crazy reason. You can drop down to the stdlib level -- do all your formatting with sprintf into your own buffer, and then you can control the encoding when creating an NSString from that -- but that's cumbersome. If anyone knows a convenient workaround, I'm all ears.

Upvotes: 0

Jed Smith
Jed Smith

Reputation: 15934

Yes, just like printf.

According to the documentation, stringWithFormat: obeys the IEEE printf specification, which allows all kinds of modifications on the individual arguments. The documentation has a restricted subset of that information, but they link to the OpenGroup printf specification for Unix to give the full information (worth a read, you can accomplish a lot of tricks with format specifiers).

Try this, to get exactly what you've pasted above:

NSString *word = @"butterfly";
NSUInteger rank = 4;
NSString *str = [NSString stringWithFormat:@"word:%-11s rank:%u", [word UTF8String], rank];

Here's an example of how I format my debugging output (I don't use NSLog, I wrap printing to standard error to get file and line, too):

fprintf(stderr, "%s | %30s:%-5d | %s", [[[NSDate date] description] UTF8String],
    [fileName UTF8String], line, [body UTF8String]);

Upvotes: 1

Anthony Cramp
Anthony Cramp

Reputation: 4585

The following seems to work, but requires conversion from your NSString's to C-strings.

NSString *word = @"tree";
NSUInteger rank = 4;
NSString *str = [NSString stringWithFormat:@"word:%-20s rank:%u", [word UTF8String], rank];
NSLog(@"%@", str);

Don't know why the field width is being ignored when trying to use an NSString.

Upvotes: 17

Related Questions