Swift中String与CChar数组的转换
2015-10-16 18:35:10 | 来源:玩转帮会 | 投稿:佚名 | 编辑:小柯

原标题:Swift中String与CChar数组的转换

Swift 中 String 与 CChar 数组的转换 - 技术文摘 | 玩赚乐

在现阶段Swift的编码中,我们还是有很多场景需要调用一些C函数。在Swift与C的混编中,经常遇到的一个问题就是需要在两者中互相转换字符串。在C语言中,字符串通常是用一个char数组来表示,在Swift中,是用CChar数组来表示。从CChar的定义可以看到,其实际上是一个Int8类型,如下所示:

///TheC'char'type.
///
///Thiswillbethesameaseither`CSignedChar`(inthecommon
///case)or`CUnsignedChar`,dependingontheplatform.
publictypealiasCChar=Int8

如果我们想将一个String转换成一个CChar数组,则可以使用String的cStringUsingEncoding方法,它是String扩展中的一个方法,其声明如下:

///Returnsarepresentationofthe`String`asaCstring
///usingagivenencoding.
@warn_unused_result
publicfunccStringUsingEncoding(encoding:NSStringEncoding)->[CChar]?

参数指定的是编码格式,我们一般指定为NSUTF8StringEncoding,因此下面这段代码:

letstr:String="abc1个"
//String转换为CChar数组
letcharArray:[CChar]=str.cStringUsingEncoding(NSUTF8StringEncoding)!

其输出结果是:

[97,98,99,49,-28,-72,-86,0]

可以看到"个"字由三个字节表示,这是因为Swift的字符串是Unicode编码格式,一个字符可能由1个或多个字节组成。另外需要注意的是CChar数组的最后一个元素是0,它表示的是一个字符串结束标志符n。

我们知道,在C语言中,一个数组还可以使用指针来表示,所以字符串也可以用char *来表示。在Swift中,指针是使用UnsafePointer或UnsafeMutablePointer来包装的,因此,char指针可以表示为UnsafePointer ,不过它与[CChar]是两个不同的类型,所以以下代码会报编译器错误:

//Error:Cannotconvertvalueoftype'[CChar]'tospecifiedtype'UnsafePointer'
letcharArray2:UnsafePointer=str.cStringUsingEncoding(NSUTF8StringEncoding)!

不过有意思的是我们可以直接将String字符串传递给带有UnsafePointer 参数的函数或方法,如以下代码所示:

funclength(s:UnsafePointer){
print(strlen(s))
}
length(str)
//输出:7n

而String字符串却不能传递给带有[CChar]参数的函数或方法,如以下代码会报错误:

funclength2(s:[CChar]){
print(strlen(s))
}
//Error:Cannotconvertvalueoftype'String'toexpectedargumenttype'[CChar]'
length2(str)

实际上,在C语言中,我们在使用数组参数时,很少以数组的形式来定义参数,则大多是通过指针方式来定义数组参数。

如果想从[CChar]数组中获取一上String字符串,则可以使用String的fromCString方法,其声明如下:

///Createsanew`String`bycopyingthenul-terminatedUTF-8data
///referencedbya`CString`.
///
///Returns`nil`ifthe`CString`is`NULL`orifitcontainsill-formed
///UTF-8codeunitsequences.
@warn_unused_result
publicstaticfuncfromCString(cs:UnsafePointer)->String?

从注释可以看到,它会将UTF-8数据拷贝以新字符串中。如下示例:

letchars:[CChar]=[99,100,101,0]
letstr2:String=String.fromCString(chars)!
//输出:cde

这里需要注意的一个问题是,CChar数组必须以0结束,否则会有不可预料的结果。在我的Playground示例代码中,如果没有0,报了以下错误:

Executionwasinterrupted.reason:EXC_BAD_INSTRUCTION

还有可能出现的情况是CChar数组的存储区域正好覆盖了之前某一对象的区域,这一对象有一个可以表示字符串结尾的标识位,则这时候,str2输出的可能是"cde1一"。

小结

在Swift中,String是由独立编码的Unicode字符组成的,即Character。一个Character可能包括一个或多个字节。所以将String字符串转换成C语言的char *时,数组元素的个数与String字符的个数不一定相同(即在Swift中,与str.characters.count计算出来的值不一定相等)。这一点需要注意。另外还需要注意的就是将CChar数组转换为String时,数组最后一个元素应当为字符串结束标志符,即0。

参考

  1. UTF8String

  2. String Structure Reference

  3. The Swift Programming Language中文版

tags:

上一篇  下一篇

相关:

特效化妆师大对决第一至八季/全集FaceOff迅雷预告

特效化妆师大对决 第一、二、三、三、四、五、六、七季 Face Off Season 6 (2014) 本季看点:Syfy真人秀节目

美国之声第七至九季/全集TheVoiceUS迅雷预告

英文译名The Voice US,第7季(2014)NBC. 本季看点:《美国之声 第七季》据多家外媒报道,泰勒·斯威夫

深夜惊奇·纪念丛飞

不知道还有没有人记得丛飞?男歌手,参加 400 多场义演,累计捐款 300 多万,资助 183 名贫困儿童,为了供贫

2012年科幻电影大全

2012年科幻电影大全 博主整理出来的2012年上映的科幻电影,可点击片名进入百度百科查看影片资料,点击豆瓣

新款魔性消除游戏来了,根本停不下来!

很多爆红的游戏往往玩法都非常简单,但却就是魔性让人停不下来。《2048》、《Flappy Bird》、经典的《俄罗

除了玫瑰金贴纸,还有一种方法可以让iPhone6变成6s

iPhone 6s 和 iPhone 6 实在太像了。就像随 5s 推出的土豪金贴膜一样,还有人用玫瑰金外壳让手里的 iPhone

看台“塌”下去一块,这个体育馆就成了有趣的空间

在荷兰阿姆斯特丹的一个网球俱乐部(Tennish Club IJburg)里,球场旁边的房屋“塌陷”了下去,这不是什么

外形不变就是不行?有消息说iPhone6s卖得比6差

尽管 iPhone 6s 和 6s Plus 正式发售三天卖出 1300 万台,打破了 iPhone 6 和 6 Plus 的纪录,但这个势头可

喝茶的讲究 错误的喝茶竟会导致癌症


  中国的茶文化源远流长,很多人都喜欢喝茶品茶,喝茶的好处有很多,

吴莫愁《大美丽My Lips》MV完整版剧情介绍 分饰多个角色






今日,吴莫愁《大美丽My Lips》MV首度曝光。作为第二张专辑《接近无限》中的第一

站长推荐: