Swift,stringWithFormat,%s给出了奇怪的结果

时间:2017-03-23 18:37:14

标签: swift printf stringwithformat

我整天都在寻找答案,但没有真正接近回答我的问题。我试图在Swift中使用stringWithFormat,但在使用printf格式字符串时。我遇到的实际问题是%s。无论我如何尝试,我似乎无法找到原始字符串。

任何帮助都会非常感激(或解决方法)。 我已经做过的事情:尝试了cString的所有可用编码,尝试创建一个用于此的ObjC函数,但是当我从Swift传递参数时,我遇到与%s相同的奇怪问题,即使在ObjC中硬编码函数体似乎打印出实际正确的String。

请在下面的示例代码中找到。

非常感谢!

var str = "Age %2$i, Name: %1$s"
let name = "Michael".cString(using: .utf8)!
let a = String.init(format: str, name, 1234)

我认为预期的结果很清楚,但是我得到的是这样的东西而不是正确的名字:

"Age 1234, Name: ÿQ5"

2 个答案:

答案 0 :(得分:3)

使用withCString()使用C字符串调用函数 表示Swift字符串。另请注意%ld是正确的 Swift Int的格式(可以是32位或64位整数)。

let str = "Age %2$ld, Name: %1$s"
let name = "Michael"

let a = name.withCString { String(format: str, $0, 1234) }
print(a) // Age 1234, Name: Michael

另一种可能的选择是创建(临时)副本 C字符串表示 (使用Swift字符串在传递给带有const char *参数的C函数时自动转换为C字符串的事实, 正如String value to UnsafePointer<UInt8> function parameter behavior中所述):

let str = "Age %2$ld, Name: %1$s"
let name = "Michael"

let nameCString = strdup(name)!

let a = String(format: str, nameCString, 1234)
print(a)

free(nameCString)

假设您的代码无法正常工作,因为name (代码中的类型为[CChar])桥接到NSArray, 然后将该数组的地址传递给字符串 格式化方法。

答案 1 :(得分:1)

使用"%1$@"代替"%1$s",并且不要使用cString调用。

这对我有用:

var str = "Age %2$i, Name: %1$@"
let name = "Michael"
let a = String.init(format: str, name, 1234)