当前位置: 首页 > 面试题库 >

在Swift中使用C字符串,或者:如何转换UnsafePointer 到CString

宋和颂
2023-03-14
问题内容

在Swift中使用标准C库函数时,在传递C字符串时遇到了问题。作为一个简单示例(仅用于演示问题),标准C库函数

char * strdup(const char *s1);

暴露给Swift

func strdup(_: CString) -> UnsafePointer<CChar>

这意味着strdup()无法将返回值传递给另一个strdup()调用:

let s1 : CString = "abc"
let s2 = strdup(s1) // OK, s2 is a UnsafePointer<CChar>
let s3 = strdup(s2) // error: could not find an overload for '__conversion' that accepts the supplied arguments

我的问题是:
如何建立一个斯威夫特CStringUnsafePointer<CChar>,使得由一个标准库函数返回的C字符串可以传递到另一个函数?

我能找到的唯一方法是使用“如何在Swift语言中将字符串转换为CString?”中的代码

let s2a = String.fromCString(s2).bridgeToObjectiveC().UTF8String
let s3 = strdup(s2a)

但是我发现这并不令人满意,原因有两个:

  • 对于一个简单的任务来说太复杂了。
  • (主要原因:) 仅当C字符串是有效的UTF-8字符串时,以上转换才有效,否则它将因运行时异常而失败。但是C字符串是 由NUL字符分隔的 任意 字符序列。

备注/背景: 当然,使用诸如Swift String或Objective-C之类的高级数据结构的高级函数NSString是更可取的。但是,标准C库中有BSD函数,它们在Foundation框架中没有完全对应的功能。

我在尝试回答在Swift中访问temp目录时遇到了这个问题。这里,mkdtemp()是一个BSD函数,没有确切的NSFileManager替代项(据我所知)。
mkdtemp()返回一个UnsafePointer<CChar>必须被传递给
NSFileManager函数stringWithFileSystemRepresentation这需要一个CString 说法。

更新: 从Xcode 6 beta 6开始,此问题不再存在,因为已简化了C字符串到Swift的映射。你可以写

let s1 = "abc"      // String
let s2 = strdup(s1) // UnsafeMutablePointer<Int8>
let s3 = strdup(s2) // UnsafeMutablePointer<Int8>
let s4 = String.fromCString(s3) // String

问题答案:

Swift 1.1(或更早的版本)具有更好的C字符串桥接功能:

let haystack = "This is a simple string"
let needle = "simple"
let result = String.fromCString(strstr(haystack, needle))

CString类型是完全消失。



 类似资料:
  • 问题内容: 当我使用的方法时 我不知道如何转换 为和长度 如何迅速做到这一点? 问题答案: 您必须先将字符串转换为UTF-8数据 然后将其写入输出流 该转换是必要的,因为有型,而不是如预期的 方法。 Swift 3更新:

  • 问题内容: 我有一个ac api返回一个以null终止的字符串,该字符串是类型数组(将对应于)。 Swift具有初始值设定项,但参数必须为(aka ),并且在两者之间没有简单的转换方法。 如何从以null终止的c字符串转换为Swift字符串? 问题答案: 在Swift 3中,有两个初始化程序 因此,可以从(空终止)有符号和无符号字符序列创建它。所以 应该工作。 有另一个初始化器 该 失败 上形成不

  • 问题内容: 我学得很快,并且对将日期String转换为NSDate转换为string感到震惊。我正在以以下格式获取日期字符串:“2015年10月22日星期四07:45:17 +0000”。我需要以MM-dd-yyyy格式显示日期。我尝试了以下代码,但返回“ null”。 谁能帮忙哪里出问题了?期待帮助。提前致谢。 问题答案: 首先,您需要使用其格式将字符串转换为NSDate。然后,将更改为简单格式

  • 问题内容: 如何在Swift中将字符串转换为Unicode(UTF-8)字符串? 在Objective中,我可以这样写: 如何在Swift中做类似的事情? 问题答案: 使用此代码, 希望对您有所帮助

  • 问题内容: 我试图将dispatch_queue_create与我在运行时创建的动态字符串一起用作第一个参数。编译器抱怨,因为它期望使用标准的c字符串。如果我将其切换为编译时定义的字符串,错误就会消失。谁能告诉我如何将String转换为标准c字符串? 问题答案: 您可以得到如下: 编辑: Beta 5更新- 不再存在(感谢@Sam):

  • 问题内容: 该应用程序基本上通过输入初始速度和最终速度以及时间来计算加速度,然后使用公式来计算加速度。但是,由于文本框中的值是字符串,所以我无法将它们转换为整数。 问题答案: 基本概念, 请注意,这仅在Swift 1.x中有效 Swift 4更新