Swift 3:将以空字符结尾的UnsafePointer<UInt8>转换为字符串

7

我有一个返回以unsigned char*数组形式表示的空结尾字符串的C API(这对应于UnsafePointer<UInt8>)。

Swift有初始化程序String(validatingUTF8:),但参数必须是UnsafePointer<CChar>(又名UnsafePointer<Int8>),并且没有简单的方法在两者之间转换。

如何从这个空结尾C字符串转换为Swift字符串?

1个回答

14

在Swift 3中,String有两个初始化函数

public init(cString: UnsafePointer<CChar>)
public init(cString: UnsafePointer<UInt8>)
因此,它可以由有符号和无符号字符(以 null 结尾)序列创建。因此。
let s = String(cString: yourCharPointer)

应该只需正常工作。


String还有另一个初始化器。

public init?(validatingUTF8 cString: UnsafePointer<CChar>)

这个方法在处理格式不正确的UTF-8序列时将失败,而不是用替换字符来代替。这个init方法没有使用无符号字符的对应方法。

通过使用CString.swift中现有的实现作为示例,将其作为扩展添加并不太困难:

extension String {
    public init?(validatingUTF8 cString: UnsafePointer<UInt8>) {
        guard let (s, _) = String.decodeCString(cString, as: UTF8.self,
                                                repairingInvalidCodeUnits: false) else {
            return nil
        }
        self = s
    }
}

然后

if let s = String(validatingUTF8: yourCharPointer) {
    print(s)
} else {
    print("invalid UTF-8")
}

同时还可处理以空字符结尾的有符号和无符号字符序列。


明白了。它没有出现在我的自动完成里。 - AthanasiusOfAlex
在 Swift 5.7 和 Xcode 14 中,init(validatingUTF8:...) 和 init(cSting:....) 已经被弃用了 :( ,对于这个变化有什么建议吗? - Ramin
@Ramin: 我建议的 extension String { ... } 代码没有使用那个方法,而是使用了 String.decodeCString()。这段代码有问题吗? - Martin R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接