你好,歡迎來到IOS教程網

 Ios教程網 >> IOS訊息 >> 關於IOS >> Swift 中 String 與 CChar 數組的轉換

Swift 中 String 與 CChar 數組的轉換

編輯:關於IOS

Swift 中 String 與 CChar 數組的轉換

在現階段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_result public 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_result public 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。

參考

  1. UTF8String

  2. String Structure Reference

  3. The Swift Programming Language中文版

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved