2016-06-29 35 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常量,所以它需要一个局部变量来进行修改。 –