6

I would like to be able to right align a string using spaces. I have to be able to use the stringWithFormat: method.

So far I have tried the recommended format and it does not seem to work: [NSString stringWithFormat:@"%10@",@"test"].

I would expect this to return a string that has six spaces followed by "test" but all I am getting is "test" with no spaces.

zachzurn
  • 2,161
  • 14
  • 26
  • For right *padding* I generally just append a long string of blanks and then truncate to the desired length. For right *alignment* you can do something similar, only truncate from the opposite end. – Hot Licks Feb 12 '13 at 02:08

2 Answers2

5

It appears that stringWithFormat ignores the sizing requests of the %@ format specifier. However, %s specifier works correctly:

NSString *test = @"test";
NSString *str = [NSString stringWithFormat:@"%10s", [test cStringUsingEncoding:NSASCIIStringEncoding]];
NSLog(@"'%@'", str);

This prints ' test'.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 2
    Since `NSString` can have about any Unicode character, it would be better to use `[test UTF8String]` instead of converting to ASCII. – rmaddy Feb 12 '13 at 01:14
  • This worked for me. Any ideas on why it does not work with '%@'? – zachzurn Feb 12 '13 at 01:20
  • 1
    @zachzurn It is a shame that Apple's implementation of the `%@` format specifier doesn't honor the standard modifiers from the IEEE spec for `%s`. Though this is an easy enough workaround. Of course a more general solution that will work with any object would be to use `[[someObject description] UTF8String]`. – rmaddy Feb 12 '13 at 01:23
  • @zachzurn My best guess is that people behind the Apple libraries decided that objects are already given a way to deal with their own padding in the `description` method, so adding a second way is unnecessary. C strings, ints, etc., on the other hand, are plain, method-less types, so adding some formatting capabilities was necessary. Again, this is only my guess. – Sergey Kalinichenko Feb 12 '13 at 01:26
  • @rmaddy I agree. Apple explicitly states that they follow the IEEE spec for 'stringWithFormat' here: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html – zachzurn Feb 12 '13 at 01:26
  • 4
    @zachzurn Keep in mind that `%@` is not part of the IEEE specification. So they can say they follow the spec (because they do) plus they added support for %@ for Objective-C objects. I just filed a bug report asking for the same modifier support for `%@` as for `%s`. – rmaddy Feb 12 '13 at 01:33
  • @dasblinkenlight The `description` method could be implemented such that the desired padding is added to the output. But there is a small issue here. `%@` is used with any `NSObject` based object including `NSString`. Since we have no control over the `description` method of `NSString`, it would be nice for `%@` to support modifiers like `%s`. Calls to the `description` method must never be relied upon, except for when used with `NSString`. – rmaddy Feb 12 '13 at 01:40
  • I suspect the main reason for %@ not respecting format modifiers like size - is that it really is NOT a format, but rather a call to the object's "description" method, whose format is not known in advance (think NSDictionary, or NSArray's description --- how can you "size" these, or any custom made object description?) – Motti Shneor Aug 04 '19 at 15:22
  • It is important to remember, that on iOS/Mac-OS and all other places where NSString is used - alignment of text should NOT base on padding with spaces - because the widths of both spaces and other characters are NOT the same - except for very specific (monospaced) fonts. – Motti Shneor Aug 08 '19 at 07:22
3

It's C style formatting. %nd means the width is n.

check following code.

NSLog(@"%10@",[NSString stringWithFormat:@"%10@",@"test"]);
NSLog(@"%@",[NSString stringWithFormat:@"      %@",@"test"]);
NSLog(@"%10@", @"test");
NSLog(@"%10s", [@"test" cStringUsingEncoding:[NSString defaultCStringEncoding]]);
NSLog(@"%10d", 1);

NSString *str = @"test";
int padding = 10-[str length]; //6
if (padding > 0) 
{
   NSString *pad = [[NSString string] stringByPaddingToLength:padding withString:@" " startingAtIndex:0];
   str = [pad stringByAppendingString:str];
}
NSLog(@"%@", str);
bitmapdata.com
  • 9,572
  • 5
  • 35
  • 43
  • It's so much easier to use `%s` instead of `%@`. Just convert the `NSString` to a C-string using `UTF8String`. `%@` honors the width specifier. – rmaddy Feb 12 '13 at 01:16
  • 2
    You can replace `[NSString string]` with `@""`. – rmaddy Feb 12 '13 at 01:19
  • @maddy the UTF8String is not bound to return anything, and will only work if the actual NSString instance has one, contiguous block of UTF8 characters as its underlying storage. In any other case (other encoding, large strings that became linked-lists etc.) this method returns nil – Motti Shneor Aug 08 '19 at 07:25