如何在swift中格式化固定长度的字符串

时间:2014-12-08 11:12:13

标签: swift

例如: var str = String(格式:“%12s - %s”,“key”,“value”)

我想要的是钥匙将保持长度为12的字符。 key__________ - 值

(这里是下划线的空格)

感谢。

6 个答案:

答案 0 :(得分:6)

正如文档所说,COpaquePointer是不透明C指针的包装器。 不透明指针用于表示无法在Swift中表示的类型的C指针,例如不完整的结构类型。

Key是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"

答案 1 :(得分:4)

基本上,要使用String格式化String(format: _:...),我们可以使用%@

String(format: "%@ - %@", "key", "value")

但是,我相信%@不支持"宽度"修饰符:你不能%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"

答案 2 :(得分:2)

没有COpaquePointer的Swift 2版本:

import Foundation
let str = "hi".nulTerminatedUTF8
let padded = str.withUnsafeBufferPointer() {
    return String(format: "%-12s", $0.baseAddress!)
}

print(padded)

斯威夫特3:

import Foundation
let str = "hi".utf8CString
let padded = str.withUnsafeBufferPointer() {
    return String(format: "%-12s", $0.baseAddress!)
}

print(padded)

答案 3 :(得分:0)

首先构建格式字符串:

let formatString = String(format: "%%%ds", key)  // gives "%12s" if key is 12
let str = String(format: formatString, value)

答案 4 :(得分:0)

Swift 4的更新

注意:使用%s格式化的字符串不能正确表示像emojis和“ä”,“ö”,“ü”,“ß”这样的unicode字符。

在Swift代码中使用%s解决一般问题有两种简单的方法:

界面: String(format: String, arguments: CVarArg...)

1。如果arguments: CVarArg...

中只有一个字符串
let stringToFormat = "test"
let formattedString = stringToFormat.withCString{
    String(format: "%s", $0)
}

如果你需要使用多个字符串,这非常繁琐,你必须使用嵌套的闭包。

...因此

2。 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)

答案 5 :(得分:0)

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".