Swift:格式化字符串宽度

时间:2016-06-29 14:59:47

标签: swift string format

我想要做的是在C / C ++,Java和许多其他语言中非常简单。我想要做的就是能够指定字符串的宽度,类似于:

printf("%-15s", var);

这将创建15个字符的字段宽度。我做了很多谷歌搜索。我已尝试以各种方式使用COpaquepointer以及String(format:,但没有运气。任何建议将不胜感激。谷歌搜索时我可能会错过一些东西。

6 个答案:

答案 0 :(得分:2)

你最好自己动手

let str0 = "alpha"
let length = 20
// right justify
var str20r = String(count: (length - str0.characters.count), repeatedValue: Character(" "))
str20r.appendContentsOf(str0)
// "               alpha"

// left justify
var str20l = str0
str20l.appendContentsOf(String(count: (length - str0.characters.count), repeatedValue: Character(" ")))
// "alpha               "

如果您需要更通用的内容'

func formatString(str: String, fixLenght: Int, spacer: Character = Character(" "), justifyToTheRigth: Bool = false)->String {
    let c = str.characters.count
    let start = str.characters.startIndex
    let end = str.characters.endIndex
    var str = str
    if c > fixLenght {
        switch justifyToTheRigth {
        case true:
            let range = start.advancedBy(c - fixLenght)..<end
            return String(str.characters[range])
        case false:
            let range = start..<end.advancedBy(fixLenght - c)
            return String(str.characters[range])
        }
    } else {
        var extraSpace = String(count: fixLenght - c, repeatedValue: spacer)
        if justifyToTheRigth {
            extraSpace.appendContentsOf(str)
            return extraSpace
        } else {
            str.appendContentsOf(extraSpace)
            return str
        }
    }
}

let str = "ABCDEFGH"
let s0 = formatString(str, fixLenght: 3)
let s1 = formatString(str, fixLenght: 3, justifyToTheRigth: true)
let s2 = formatString(str, fixLenght: 10, spacer: Character("-"))
let s3 = formatString(str, fixLenght: 10, spacer: Character("-"), justifyToTheRigth: true)

print(s0)
print(s1)
print(s2)
print(s3)

打印

ABC
FGH
ABCDEFGH--
--ABCDEFGH

答案 1 :(得分:1)

问题是Swift字符串具有可变大小的元素,因此它的含义不明确是什么&#34; 15个字符&#34;是。这是简单字符串的挫败感 - 但在处理表情符号,区域标识符,连字等时使语言更加精确。

您可以将Swift字符串转换为C字符串并使用普通格式化程序(请参阅Santosh的回答)。 &#34; Swift&#34;处理字符串的方法是从Character s的集合的起始索引开始并提前N次。例如:

let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

let index = alphabet.characters.startIndex.advancedBy(14) // String.CharacterView.Index
let allChars = alphabet.characters.prefixThrough(index) // String.CharacterView

print(String(allChars)) // "ABCDEFGHIJKLMNO\n"

如果你想强制填充,你可以使用这样的方法:

extension String {
    func formatted(characterCount characterCount:Int) -> String {
        if characterCount < characters.count {
            return String(characters.prefixThrough(characters.startIndex.advancedBy(characterCount - 1)))
        } else {
            return self + String(count: characterCount - characters.count, repeatedValue: " " as Character)
        }
    }
}

let abc = "ABC"
let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

print("!\(abc.formatted(characterCount: 15))!")
// "!ABC            !\n"

print("!\(alphabet.formatted(characterCount: 15))!")
// "!ABCDEFGHIJKLMNOP!\n"

答案 2 :(得分:1)

您可以使用withCString将字符串快速转换为字节数组(技术上为UnsafePointer<Int8>):

let str = "Hello world"
let formatted = str.withCString { String(format: "%-15s", $0) }

print("'\(formatted)'")

答案 3 :(得分:1)

一方面,%@用于格式化String对象:

import Foundation

var str = "Hello"
print(String(format: "%@", str))

但它不支持宽度修饰符:

print(String(format: "%-15@", str))

仍会打印未填充的文字:

"Hello\n"

但是有一个修饰符%s似乎适用于CStrings:

var cstr = (str as NSString).utf8String //iOS10+ or .UTF8String otherwise

print(String(format: "%-15s", cstr!))

输出:

"Hello          \n"

一个好处是你可以使用与NSLog相同的格式规范:

NSLog("%-15s", cstr!)

答案 4 :(得分:0)

你试过这个吗?

let string1 = "string1"
let string2 = "string2"
let formattedString = String(format: "%-15s - %s",
             COpaquePointer(string1.cStringUsingEncoding(NSUTF8StringEncoding)!),
             COpaquePointer(string2.cStringUsingEncoding(NSUTF8StringEncoding)!)
)

print(formattedString)
//string1         - string2

答案 5 :(得分:0)

我们现在有了很多有趣的答案。谢谢大家。我写了以下内容:

func formatLeftJustifiedWidthSpecifier(stringToChange: String, width: Int) -> String {

    var newString: String = stringToChange
    newString = newString.stringByPaddingToLength(width, withString: " ", startingAtIndex: 0)
    return newString
}