例如:
var str = String(format: "%12s - %s", "key", "value")
我想要的是key将保持长度为12个字符。 key__________ - value (这里的下划线是空格)
谢谢。
我想要的是key将保持长度为12个字符。 key__________ - value (这里的下划线是空格)
谢谢。
COpaquePointer
是一个不透明的 C 指针的包装器。不透明指针用于表示不能在 Swift 中表示的类型的 C 指针,例如不完整的结构体类型。String
- 原生的 Swift 类型。我相信最好使用这个 Swift String 函数:let testString = "bla bli blah"
testString.stringByPaddingToLength(3, withString: " ", startingAtIndex: 0)
//output = "bla"
Swift 3
let testString = "bla bli blah"
testString.padding(toLength: 3, withPad: " ", startingAt: 0)
//output = "bla"
String(format: _:...)
格式化String
,我们可以使用%@
:String(format: "%@ - %@", "key", "value")
但是,我相信%@
不支持 "width" 修饰符:你不能像这样使用 %12@
。
因此,您必须将String
转换为COpaquePointer
,然后可以使用%s
格式化:
var key = "key"
var val = "value"
var str = String(format: "%-12s - %s",
COpaquePointer(key.cStringUsingEncoding(NSUTF8StringEncoding)!),
COpaquePointer(val.cStringUsingEncoding(NSUTF8StringEncoding)!)
)
// -> "key - value"
Swift 5.1 / Xcode 11.1 / iOS 13
这确实是最佳答案。没有 C 字符串转换(破坏字形簇),没有 UnsafeBufferPointer。
public extension String {
func paddedToWidth(_ width: Int) -> String {
let length = self.count
guard length < width else {
return self
}
let spaces = Array<Character>.init(repeating: " ", count: width - length)
return self + spaces
}
}
然后,要使用它,您可以这样做:
let fubar = "Foobar".paddedToWidth(10) + "Barfoo"
print(fubar)
// Prints "Foobar Barfoo".
不使用COpaquePointer的Swift 2版本:
import Foundation
let str = "hi".nulTerminatedUTF8
let padded = str.withUnsafeBufferPointer() {
return String(format: "%-12s", $0.baseAddress!)
}
print(padded)
Swift 3:
import Foundation
let str = "hi".utf8CString
let padded = str.withUnsafeBufferPointer() {
return String(format: "%-12s", $0.baseAddress!)
}
print(padded)
注意:使用%s
格式化的字符串无法正确表示像表情符号和“ä”、“ö”、“ü”、“ß”这样的Unicode字符。
有两种简单的方法可以解决Swift代码中%s
的一般问题:
接口:String(format: String, arguments: CVarArg...)
arguments: CVarArg...
中只有一个字符串let stringToFormat = "test"
let formattedString = stringToFormat.withCString{
String(format: "%s", $0)
}
arguments: CVarArg...
中使用不同的字符串。String
的计算属性c
。extension String {
// nested `struct` which is needed
// to keep the `baseAdress` pointer valid (see (*))
struct CString: CVarArg {
// needed to conform to `CVarArg`
var _cVarArgEncoding: [Int] = []
// needed to keep the `baseAdress` pointer valid (see (*))
var cstring: ContiguousArray<CChar> = []
init(string: String) {
// is essentially just a (special) `Array`
cstring = string.utf8CString
self._cVarArgEncoding = cstring.withUnsafeBufferPointer{
// use the `_cVarArgEncoding` of the first Buffer address (*)
$0.baseAddress!._cVarArgEncoding
}
}
}
// you only need to use this property (`c` stands for `CString`)
// e.g.: String(format: "%s", "test".c)
var c: CString {
return CString(string: self)
}
}
用法
let stringToFormat1 = "test1"
let stringToFormat2 = "test2"
// note the `.c` at the end of each variable/literal
let formattedString = String(format: "%s %s %s", stringToFormat1.c, stringToFormat2.c, "test3".c)
使用第二种解决方案:
// note: it should be `-12` instead of `12` in order to pad the string to the right
var str = String(format: "%-12s - %s", "key".c, "value".c)
首先构建一个格式化字符串:
let formatString = String(format: "%%%ds", key) // gives "%12s" if key is 12
let str = String(format: formatString, value)