iOS:如何在Swift中将UnsafeMutablePointer<Int8>转换为String?

20

正如标题所说,Swift中将UnsafeMutablePointer转换为String的正确方法是什么?

//lets say x = UnsafeMutablePointer<Int8> 

var str = x.memory.????

我尝试使用x.memory.description,但很明显是错误的,给了我一个错误的字符串值。


指针指向什么?UTF-8字节?以NUL结尾? - rob mayoff
假设它是一个有效的以空字符结尾的 C 字符串,您可以使用 String(CString:, encoding:) - Rob
3个回答

54

如果指针指向以UTF-8字节为结尾的C字符串,您可以这样做:

import Foundation

let x: UnsafeMutablePointer<Int8> = ...
// or UnsafePointer<Int8>
// or UnsafePointer<UInt8>
// or UnsafeMutablePointer<UInt8>

let str = String(cString: x)

3
让str等于x的CString字符串转换为Swift的String类型。 - user3441734

10

时代在变化。在Swift 3+中,您需要这样做:

如果您想要验证utf-8:

let str: String? = String(validatingUTF8: c_str)

如果你想将utf-8错误转化为Unicode错误符号:�

let str: String = String(cString: c_str)
假设 c_str 的类型为 UnsafePointer<UInt8> UnsafePointer<CChar>,这是相同的类型,并且大多数C函数返回。

1
这个:
let str: String? = String(validatingUTF8: c_str)

似乎不能与UnsafeMutablePointer<UInt8>一起使用(这是我的数据中出现的内容)。

这让我轻松地想到如何执行类似于C/Perl系统函数的操作:

let task = Process()
task.launchPath = "/bin/ls"
task.arguments = ["-lh"]

let pipe = Pipe()
task.standardOutput = pipe
task.launch()

let data = pipe.fileHandleForReading.readDataToEndOfFile()
var unsafePointer = UnsafeMutablePointer<Int8>.allocate(capacity: data.count)
data.copyBytes(to: unsafePointer, count: data.count)

let output : String = String(cString: unsafePointer)
print(output)
//let output : String? = String(validatingUTF8: unsafePointer)
//print(output!)

如果我切换到使用validatingUTF8(可选)而不是cString进行验证,我会得到这个错误:
./ls.swift:19:37: error: cannot convert value of type 'UnsafeMutablePointer<UInt8>' to expected argument type 'UnsafePointer<CChar>' (aka 'UnsafePointer<Int8>')
let output : String? = String(validatingUTF8: unsafePointer)
                                    ^~~~~~~~~~~~~

如何验证管道输出的UTF8格式(以便我不会在任何地方看到Unicode错误符号)?

(是的,我没有正确检查print()的可选项,但这不是我目前解决的问题;-)。)


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