2016-06-29 116 views
3

我想在C/C++,Java和其他許多語言中使用它非常簡單。所有我想要做的是能夠指定字符串的寬度,與此類似:Swift:格式字符串寬度

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

這將創建15個字符的字段寬度。我做了大量的搜索。我嘗試過以各種方式使用COpaquepointer以及String(format:,但沒有運氣。任何建議將不勝感激。當使用Google時,我可能會漏掉一些東西。

回答

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 
+0

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html – user3441734

+0

是。我相信我得到了exc_bad_instruction錯誤。現在,我正在寫一個自定義函數來做我想要的東西,直到我找到更好的答案。 –

1

問題是,Swift字符串具有可變大小的元素,所以它含糊不清「15個字符」是什麼。這是對簡單字符串感到沮喪的原因 - 但在處理表情符號,區域標識符,連字符等時使語言更加精確。

您可以將Swift字符串轉換爲C字符串並使用普通格式器(請參見Santosh's回答)。處理字符串的「Swift」方法是從Characters的開始索引處開始並前進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" 
+0

如果它少於15個字符,會填充一個字符串嗎? –

+0

@AlexCauthen不,它會崩潰,因爲您會超過字符串中的字符數。這只是你在Swift中如何處理字符串長度的簡單例子。 –

+1

@AlexCauthen我用一個字符串擴展更新了我的答案,它可以做你想要的 –

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

可以使用withCString到串快速轉換到字節數組(技術上的UnsafePointer<Int8>):

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

print("'\(formatted)'") 
+0

,你會得到'(「%-15s」,0x00007fcf287884b0)':-) – user3441734

+0

根據http://www.runswiftlang.com並非如此'現在不在Xcode附近,所以我不能測試 –

+0

這就是我的電腦打印....相信我(迅速2.2操場) – user3441734

1

從一方面%@用於格式化字符串對象:

import Foundation 

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

但它不支持寬度調節:

print(String(format: "%[email protected]", str)) 

仍然會打印未填補的文字:

"Hello\n" 

然而,有似乎與CStrings工作改性劑%S:

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

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

輸出:

"Hello   \n" 

一個好處您可以使用與NSLog相同的格式規格:

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

'NSString'沒有成員'utf8String' – user3441734

+0

導入Foundation和使用UTF8String,它應該工作.... – user3441734

+0

是的,嘗試UTF8String,好像在iOS10中它被替換爲小寫前綴。 – yurgis

0

我們現在有很多有趣的答案。謝謝大家。我寫道:

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

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

有幾個問題:(1)你在橋接NSString,所以你失去了Swift字符串的好處,(2)爲什麼要寫這個而不是直接調用'stringByPaddingToLength' ?,(3)':String '是不必要的,(4)爲什麼分配給'newString'只能立即覆蓋值? –

+0

我沒有意識到它橋接到NSString。謝謝你讓我知道。如果我創建了一個函數,我可以從任何地方調用它來避免代碼重複。我來自明確定義類型的背景,所以它確實是一種風格。在Swift 3.0和之後,函數參數被定義爲let常量,所以它需要一個局部變量來進行修改。 –