Swift 中 String 与 CChar 数组的转换
来源:互联网 发布:nginx访问图片 编辑:程序博客网 时间:2024/04/30 01:01
在现阶段Swift的编码中,我们还是有很多场景需要调用一些C函数。在Swift与C的混编中,经常遇到的一个问题就是需要在两者中互相转换字符串。在C语言中,字符串通常是用一个char数组来表示,在Swift中,是用CChar数组来表示。从CChar的定义可以看到,其实际上是一个Int8类型,如下所示:
/// The C 'char' type.////// This will be the same as either `CSignedChar` (in the common/// case) or `CUnsignedChar`, depending on the platform.public typealias CChar = Int8
如果我们想将一个String转换成一个CChar数组,则可以使用String的cStringUsingEncoding方法,它是String扩展中的一个方法,其声明如下:
/// Returns a representation of the `String` as a C string/// using a given encoding.@warn_unused_resultpublic func cStringUsingEncoding(encoding: NSStringEncoding) -> [CChar]?
参数指定的是编码格式,我们一般指定为NSUTF8StringEncoding,因此下面这段代码:
let str: String = "abc1个"// String转换为CChar数组let charArray: [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: Cannot convert value of type '[CChar]' to specified type 'UnsafePointer'let charArray2: UnsafePointer = str.cStringUsingEncoding(NSUTF8StringEncoding)!
不过有意思的是我们可以直接将String字符串传递给带有UnsafePointer参数的函数或方法,如以下代码所示:
func length(s: UnsafePointer) { print(strlen(s))}length(str)// 输出:7\n
而String字符串却不能传递给带有[CChar]参数的函数或方法,如以下代码会报错误:
func length2(s: [CChar]) { print(strlen(s))}// Error: Cannot convert value of type 'String' to expected argument type '[CChar]'length2(str)
实际上,在C语言中,我们在使用数组参数时,很少以数组的形式来定义参数,则大多是通过指针方式来定义数组参数。
如果想从[CChar]数组中获取一上String字符串,则可以使用String的fromCString方法,其声明如下:
/// Creates a new `String` by copying the nul-terminated UTF-8 data/// referenced by a `CString`.////// Returns `nil` if the `CString` is `NULL` or if it contains ill-formed/// UTF-8 code unit sequences.@warn_unused_resultpublic static func fromCString(cs: UnsafePointer) -> String?
从注释可以看到,它会将UTF-8数据拷贝以新字符串中。如下示例:
let chars: [CChar] = [99, 100, 101, 0]let str2: String = String.fromCString(chars)!// 输出:cde
这里需要注意的一个问题是,CChar数组必须以0结束,否则会有不可预料的结果。在我的Playground示例代码中,如果没有0,报了以下错误:
Execution was interrupted. reason: EXC_BAD_INSTRUCTION
还有可能出现的情况是CChar数组的存储区域正好覆盖了之前某一对象的区域,这一对象有一个可以表示字符串结尾的标识位,则这时候,str2输出的可能是"cde1一"。
小结
在Swift中,String是由独立编码的Unicode字符组成的,即Character。一个Character可能包括一个或多个字节。所以将String字符串转换成C语言的char *时,数组元素的个数与String字符的个数不一定相同(即在Swift中,与str.characters.count计算出来的值不一定相等)。这一点需要注意。另外还需要注意的就是将CChar数组转换为String时,数组最后一个元素应当为字符串结束标志符,即0。
参考
UTF8String
String Structure Reference
The Swift Programming Language中文版
- Swift 中 String 与 CChar 数组的转换
- 关于char 与cchar[]的输入流
- Swift中NSString与String转换
- C#中ArrayList 与 string、string[]数组 的转换
- C#中ArrayList 与 string、string[]数组 的转换
- #中ArrayList 与 string、string[]数组 的转换
- C#中ArrayList 与 string、string[]数组 的转换
- C#中ArrayList 与 string、string[]数组 的转换(转)
- C#中ArrayList 与 string、string[]数组 的转换
- C#.NET中string与byte数组的相互转换
- Java中char数组与字符串String类型的转换
- Java中String与byte数组的相互转换
- C++中字符数组与string的相互转换
- JAVA中String与int转换,list与数组转换,char数组与String转换
- Swift中实现Array数组和NSArray数组的相互转换与遍历
- String 与Byte[]数组之间的转换
- 字节数组与String类型的转换
- char数组与string的强制转换
- 常用工具类(日志、Toast、SPUtils、单位转换类、 DensityUtils、SDCardUtils、ScreenU、App相关辅助类、KeyBoardUtils、NetUtils、Http)
- SSH框架学习(四、struts+spring搭建,spring注解注入)
- Linux之/et/sysctl.conf配置文件详解
- 初识Cocos2d-JS (一)
- 创建一个流畅循环的UIScrollView
- Swift 中 String 与 CChar 数组的转换
- 公钥,私钥,SSL(讲的很生动)
- Objective-C Runtime 运行时之三:方法与消息
- memset、ZeroMemory、SecurZeroMemory
- 详细解读Jquery各Ajax函数:$.get(),$.post(),$.ajax(),$.getJSON()
- 总结 Swift 中随机数的使用
- 详解EJB技术及实现原理
- svn使用方法
- mysql 优化