10

I want to append a string to a NSMutableString using appendFormat, inserting white spaces to get a minimum length for my string.

In objective-c, i just used

[text.mutableString appendFormat:@"%-12s", "MyString"];

and I would get

"MyString    "

But in Swift, I tried

text.mutableString.appendFormat("%-12s", "MyString")

and I get everything, but not "MyString ". It appears some random characters that I do not know where it came from.

Is there anyone who knows why that happens, and what I should do?

Thank you guys!

Adam S
  • 16,144
  • 6
  • 54
  • 81
kobuchi
  • 420
  • 5
  • 11
  • I can reproduce this in a Playground, the random characters change every time the code is run. Using `str += String(format:"%-12s", "Hello")`, and variants. – Adam S Apr 21 '15 at 03:40

4 Answers4

5

Through Ken's explanation that a Swift String object is not equivalent to the Objective-C C-style string (a null-terminated array of char) I found this answer which shows how to convert a Swift String object into a Cstring, which the %-12s formatting works correctly on.

You can use your existing formatting string as follows:

text.mutableString.appendFormat("%-12s", ("MyString" as NSString).UTF8String)

Some examples:

var str = "Test"
str += String(format:"%-12s", "Hello")
// "Test–yç       " (Test, a dash, 11 random characters)

var str2 = "Test"
str2 += String(format:"%-12@", "Hello")
// "TestHello" (no padding)

var str3 = "Test"
str3 += String(format:"%-12s", ("Hello" as NSString).UTF8String)
// "TestHello       " ('Hello' string is padded out to 12 chars)
Community
  • 1
  • 1
Adam S
  • 16,144
  • 6
  • 54
  • 81
5

You should use String's method stringByPaddingToLength() as follow:

let anyString = "MyString"
let padedString = anyString.stringByPaddingToLength(12, withString: " ", startingAtIndex: 0)  // "MyString    "
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • This works well too, added an example using this method to my answer. It's much more obvious as well (where as the cstring conversion will need a comment to explain what's going on). – Adam S Apr 21 '15 at 13:17
  • In Swift 5, method name has been changed to `padding(toLength:withPad:startingAt:)`. – Jerry Krinock Aug 31 '19 at 04:51
2

Try:

text.mutableString.appendFormat("%-12@", "MyString")

In Swift, "MyString" is a String object. The %s format specifier causes appendFormat() to interpret its argument as a C-style string (a buffer of char terminated by a null char).

In Objective-C, "MyString" is just such a C-style string. You would have to prefix it with an @ to get an NSString object (@"MyString").

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • What do you mean "nothing happened"? The statement does *something*. Adam points out that Cocoa doesn't seem to respect the field width in the format specifier when using `%@`, which is disappointing. That seems like a Cocoa bug. – Ken Thomases Apr 21 '15 at 04:42
  • Thank you sir! Just one addition: Swift's `String` is not an object, afaik, it's a struct. – Sebastian Hojas Jul 28 '16 at 12:37
1
    let space: Character = " "
    text = "MyString" + String(count: 12, repeatedValue: space)
muneeb
  • 2,461
  • 1
  • 13
  • 9
  • This will simply append 12 spaces to the end of the string, rather than padding the string _up to_ a minimum of 12 characters. – Adam S Apr 21 '15 at 03:30
  • yeah the string MyString could change to another string with a different length, that's why I need something simple that could do the complex work for me – kobuchi Apr 21 '15 at 04:23