在变量参数列表中以C字符串形式传递Swift字符串
我试图使用旧的printf样式的字符串格式化程序从旧的Swift字符串定义新的Swift字符串 我注意到,只要我从一个Swift字符串文字开始,而不是一个字符串变量开始,这就可以很好地工作在变量参数列表中以C字符串形式传递Swift字符串,c,swift,C,Swift,我试图使用旧的printf样式的字符串格式化程序从旧的Swift字符串定义新的Swift字符串 我注意到,只要我从一个Swift字符串文字开始,而不是一个字符串变量开始,这就可以很好地工作 // OK! String(format:"%s", "hello world".cStringUsingEncoding(NSUTF8StringEncoding)) // ERROR: argument type '[CChar]?' does not conform to expected type
// OK!
String(format:"%s", "hello world".cStringUsingEncoding(NSUTF8StringEncoding))
// ERROR: argument type '[CChar]?' does not conform to expected type 'CVarArgType'
let s = "hello world"
String(format:"%s", s.cStringUsingEncoding(NSUTF8StringEncoding))
为什么会发生这种情况
最好的解决办法是什么
(请注意,我知道但不想使用Cocoa字符串格式化程序%@
。我想要printf样式的格式化代码,因为我实际上要做的是使用%-10s
之类的代码快速而脏兮兮的表格对齐)
这个问题与Swift 2.2有关。不要仅仅为了对齐而创建C字符串。有一种方法可以做到这一点
// Swift 2
s.stringByPaddingToLength(10, withString: " ", startingAtIndex: 0)
// Swift 3
s.padding(toLength: 10, withPad: " ", startingAt: 0)
请注意,如果字符串长度超过10个UTF-16代码单元,它将截断该字符串
这里的问题是,Swift中有两种名为
cstringusingencode
的方法:
func cstringusingencode(编码:UInt)->UnsafePointer
,作为NSString的一种方法func cStringUsingEncoding(编码:NSStringEncoding)->[CChar]?
,作为字符串的扩展s
的类型已经设置为String,因此选择了返回[CChar]?
的方法
这可以通过强制s
为NSString来解决:
let s: NSString = "hello world"
String(format:"%s", s.cStringUsingEncoding(NSUTF8StringEncoding))
肯尼特的答案显然是最好的办法 但是,对于那些仍然想知道如何以错误的方式进行操作,并且在不通过NSString的情况下访问基于Swift字符串的c字符串的人来说,这似乎也是可行的(Swift 2.2):
有趣。如果将
s
上的类型注释为String
,会发生什么情况?更简单:使用s.withCString{…}
。
var s:String = "dynamic string"
s.nulTerminatedUTF8.withUnsafeBufferPointer { (buffptr) -> String in
let retval:String = String(format:"%s",buffptr.baseAddress)
return retval
}