2016-09-16 2 views
3

У меня есть c api, который возвращает строку с нулевым завершением, которая представляет собой массив типа unsigned char* (который соответствует UnsafePointer<UInt8>).Swift 3: конвертировать UnsafePointer с нулевым завершением <UInt8> в строку

Swift имеет инициализатор String(validatingUTF8:), но аргумент должен быть UnsafePointer<CChar> (А.К.А. UnsafePointer<Int8>), и не тривиальный способ преобразования между ними.

Как преобразовать из этой c-строки с нулевым завершением в строку Swift?

ответ

8

В Swift 3, String имеет два инициализаторы

public init(cString: UnsafePointer<CChar>) 
public init(cString: UnsafePointer<UInt8>) 

поэтому он может быть создан из (NULL) с концевыми последовательностями обоих знаковых и беззнаковых символов. Таким образом,

let s = String(cString: yourCharPointer) 

должно просто работать.


String имеет другой инициализатора

public init?(validatingUTF8 cString: UnsafePointer<CChar>) 

, который терпит неудачу на плохо сформированных последовательностей UTF-8 вместо того, чтобы заменить их персонажами замены. Этот метод инициализации не имеет аналога , принимающего символы без знака.

Принимая существующие реализации в CString.swift в качестве примеров, это не слишком сложно, чтобы добавить это как расширение:

extension String { 
    public init?(validatingUTF8 cString: UnsafePointer<UInt8>) { 
     guard let (s, _) = String.decodeCString(cString, as: UTF8.self, 
               repairingInvalidCodeUnits: false) else { 
      return nil 
     } 
     self = s 
    } 
} 

, а затем

if let s = String(validatingUTF8: yourCharPointer) { 
    print(s) 
} else { 
    print("invalid UTF-8") 
} 

также работает с (завершающим нулем) последовательностей как подписанных, так и неподписанных символов.

+0

Got it. Он не появлялся в моем автозаполнении. – AthanasiusOfAlex

Смежные вопросы