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

如何在swift中格式化固定长度的字符串,swift,Swift,例如: var str=字符串(格式:“%12s-%s”,“键”,“值”) 我想要的是钥匙可以装12个字符。 键值 (此处下划线为空白) 谢谢。首先构建一个格式字符串: let formatString = String(format: "%%%ds", key) // gives "%12s" if key is 12 let str = String(format: formatString, value) 基本上,要使用字符串(格式::…)格式化字符串,我们可以使用%@: String

例如: var str=字符串(格式:“%12s-%s”,“键”,“值”)

我想要的是钥匙可以装12个字符。 键值

(此处下划线为空白)


谢谢。

首先构建一个格式字符串:

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

基本上,要使用
字符串(格式::…)
格式化
字符串
,我们可以使用
%@

String(format: "%@ - %@", "key", "value")
但是,我相信
%@
不支持“宽度”修饰符:您不能
%12@
或诸如此类

因此,您必须将
字符串
转换为
copaqueponinter
,可以使用
%s
格式化:

var key = "key"
var val = "value"

var str = String(format: "%-12s - %s",
    COpaquePointer(key.cStringUsingEncoding(NSUTF8StringEncoding)!),
    COpaquePointer(val.cStringUsingEncoding(NSUTF8StringEncoding)!)
)
// -> "key          - value"

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

键是一个
字符串
-本机Swift类型。我认为最好使用这个Swift字符串函数:

let testString = "bla bli blah"
testString.stringByPaddingToLength(3, withString: " ", startingAtIndex: 0) 
//output = "bla"
斯威夫特3

let testString = "bla bli blah"
testString.padding(toLength: 3, withPad: " ", startingAt: 0) 
//output = "bla"

Swift 2版本,不含COpaquePointer:

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)
Swift 4的更新 注意:使用
%s
格式化的字符串不能正确表示像emojis和“ä”、“ö”、“ü”、“ß”这样的unicode字符

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

接口:
String(格式:String,参数:CVarArg…)

1.如果
参数中只有一个字符串:CVarArg…
如果您需要使用多个字符串,这将变得非常乏味,您必须使用嵌套闭包

因此

2.
参数中的不同字符串:CVarArg…
我找到的最简单的方法是使用计算属性
c
String
进行扩展

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)
    }
}

你的具体问题 使用第二种解决方案:

// 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)

Swift 5.1/Xcode 11.1/iOS 13

这确实是最好的答案。没有C字符串转换(弄乱了图形集簇),没有非安全缓冲指针

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
    }
}
// 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)
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".