2015-04-15 16 views
20

konvertieren UInt8 Byte-Array Ich habe Probleme beim Konvertieren von UInt8 Byte-Array in String in String. Ich habe gesucht und eine einfache LösungWie UInt8 Byte Array in String in

String.stringWithBytes(buff, encoding: NSUTF8StringEncoding) 

finden, aber es zeigt Fehler String.type hat kein Mitglied stringWithBytes. Kann mir jemand eine Lösung vorschlagen?

Dies ist mein Code, wo ich ein NSData bekomme und in Bytes Array konvertiert und dann muss ich dieses Byte-Array in String konvertieren.

let count = data.length/sizeof(UInt8) 
var array = [UInt8](count: count, repeatedValue: 0) 
data.getBytes(&array, length:count * sizeof(UInt8)) 
String.stringWithBytes(buff, encoding: NSUTF8StringEncoding) 
+0

http://stackoverflow.com/a/24465772/986169 dies könnte Ihnen helfen – giorashc

+0

Oder versuchen http : //stackoverflow.com/questions/25554986/how-to-convert-string-to-unsafepointeruint8-and-length – emrys57

Antwort

34

Update für Swift 3/Xcode 8:

if let string = String(data: data, encoding: .utf8) { 
    print(string) 
} else { 
    print("not a valid UTF-8 sequence") 
} 

Update für Swift 2/Xcode 7:

if let str = String(data: data, encoding: NSUTF8StringEncoding) { 
    print(str) 
} else { 
    print("not a valid UTF-8 sequence") 
} 

Zurück Antwort:

String hat keine stringWithBytes() Methode. NSString eine

NSString(bytes: , length: , encoding:) 

Methode hat, die Sie verwenden können, aber Sie können für eine UInt8 Array die Zeichenfolge direkt von NSData, ohne die Notwendigkeit zu erstellen:

if let str = NSString(data: data, encoding: NSUTF8StringEncoding) as? String { 
    println(str) 
} else { 
    println("not a valid UTF-8 sequence") 
} 
0

„MSString (Bytes:, Länge: , encoding:) "scheint nicht zu funktionieren ab dem 26. Juli 2015

Konvertieren von Bytewerten in ASCII scheint problematisch, wenn Sie eine Wand getroffen haben, können Sie es auf die harte Art wie folgt tun (und können Ich vermisse etwas mit swift, aber innerhalb meines Zeitrahmens konnte ich keine Lösungen finden.) Dies wird mit zwei Funktionen geschehen. Die erste Funktion akzeptiert einen UInt8 und konvertiert diesen in eine "\ u {}" - Repräsentation, die dann von der Funktion zurückgegeben wird. Zweitens wird eine andere Funktion eingerichtet, die ein UInt8-Array als Parameter aufnimmt und dann eine Zeichenfolge ausgibt.

Schritt # 1. Funktion konvertiert jedes Byte auf "\ u {} somenumber"

func convertToCharacters(#UInt8Bits : UInt8) -> String {

var characterToReturn : String 

switch UInt8Bits{ 

case 0x00: characterToReturn = "\u{0}" 
case 0x01: characterToReturn = "\u{1}" 
case 0x02: characterToReturn = "\u{2}" 
case 0x03: characterToReturn = "\u{3}" 
case 0x04: characterToReturn = "\u{4}" 

// .. für so viele Zeichen hinzufügen, wie Sie erwarten ... vergessen Sie nicht, Basis 16 ..

case 0x09: characterToReturn = "\u{09}" 
case 0x0A: characterToReturn = "\u{0A}" 

default: characterToReturn = "\u{0}" 

/* .. und den ganzen Weg bis zu 0xff */

case 0xFE: characterToReturn = "\u{FE}" 
case 0xFF: characterToReturn = "\u{FF}" 



    } 

return characterToReturn

}

Schritt # 2 ...Als nächstes wird eine Funktion, die in einem Array UInt8 als Parameter dann eine Zeichenfolge zurück ...

func UInt8ArrayToString(#UInt8Array: [UInt8]) -> String {

var returnString : String = "" for eachUInt8Byte in UInt8Array {

returnString += convertToCharacter(UInt8Bits: eachUInt8Byte)

}

return returnString }

Dieses in einem Swift Spielplatz funktionieren sollte Machen Sie ein Array

var myArray: [UInt8] = [0x30, 0x3A, 0x4B]

// gelten dann die verschiedenen Funktionen, die oben

println (UInt8ArrayToString (UInt8Array: myArray))

+0

Könnten Sie Ihre Aussage klären * "" NSString (Bytes:, Länge:, Codierung:) "wird nicht angezeigt arbeiten ... "? - Ich habe das mit Xcode 7 beta 5 überprüft und keine Probleme festgestellt. –

+0

Ich habe ein Problem damit. Wir machen xor von zwei UInt8s und was passiert, ist, dass das xor-Ergebnis einen korrekten UInt8 liefert, aber der NSString (Bytes, ...) die Zeichenfolge nicht konvertiert. Wenn ich Playground verwende und Zeichenfolgen anpassen, die ein Ergebnis zurückgeben, bevor Base16 gestartet wird, funktioniert der NSString (Bytes, ...). – Josh

4

Diese Lösung funktioniert.

NSString(bytes: data!, length: data!.count, encoding: NSUTF8StringEncoding) 
1

Nicht sehr elegant oder ‚Swifty‘, aber das ist einfach und es funktioniert:

let i: UInt8 = 65 
let s = String(format: "%c", i) // A 

ich Stunden für eine einfache Möglichkeit suchen vergeudet, dies zu tun, bevor ich von ‚printf‘ dachte plötzlich von meinen Unix Scripting Tagen!

6

Dieser arbeitete für mich:

String(bytes: bytes, encoding: NSUTF8StringEncoding) 
3

Martin R in https://stackoverflow.com/a/29644387/2214832 Sunil Kumar auf sein Problem beantwortet, aber nicht auf das Thema Frage. Das Problem weiterhin angezeigt, wenn Sie bereits UInt8 Byte-Array haben und es als Zeichenfolge darstellen müssen.

Hier ist meine Lösung:

extension String { 
    init(_ bytes: [UInt8]) { 
     self.init() 
     for b in bytes { 
      self.append(UnicodeScalar(b)) 
     } 
    } 
} 

diese Erweiterung verwenden, können Sie jetzt init String mit UInt8 Byte-Array wie folgt aus:

func testStringUInt8Extension() { 
    var cs : [UInt8] = [] 
    for char : UInt8 in 0..<255 { 
     cs.append(char) 
    } 
    print("0..255 string looks like \(String(cs)))") 
} 

Dies, weil praktisch keine ideale Lösung würden Sie entschlüsseln müssen etwas wie UTF-8-kodierten Text. Aber für ASCII-Daten funktioniert das wie erwartet.

7

Swifty Lösung

array.reduce("", combine: { $0 + String(format: "%c", $1)}) 

Hex Darstellung:

array.reduce("", combine: { $0 + String(format: "%02x", $1)}) 
+3

Swift 3: '' 'array.reduce (" ", {$ 0 + String (Format:"% c ", $ 1)})' '' –

+0

Schlechte Verwendung, wenn IMO reduziert wird. Ich würde mit 'array.map {String (Format:"% c ", $ 0)} .joined()' gehen –

0

Komplettes Beispiel für Swift 2 & 3:

import Foundation 

let bytes : [UInt8] = [72, 73] 
let nsdata = NSData(bytes: bytes as [UInt8], length: 2) 
let str = String(data: nsdata, encoding: NSUTF8StringEncoding)! // 'HI' 
3

Swift 3

folgendes gab mir einen Fehler, weil der "NSUTF8StringEncoding":

String(data: nsdata, encoding: NSUTF8StringEncoding)! 

dies in schnellen 3 für mich gearbeitet:

let xmlStr:String = String(bytes: data!, encoding: String.Encoding.utf8)! 
1

Hier einige allgemeinere Code für Strings aus einem Byte-Array zu extrahieren wo die Zeichenfolgen in UTF-8 codiert wurden.

/// Class which encapsulates a Swift byte array (an Array object with elements of type UInt8) and an 
/// index into the array. 
open class ByteArrayAndIndex { 

    private var _byteArray : [UInt8] 
    private var _arrayIndex = 0 

    public init(_ byteArray : [UInt8]) { 
     _byteArray = byteArray; 
    } 

    /// Method to get a UTF-8 encoded string preceded by a 1-byte length. 
    public func getShortString() -> String { 
     return getTextData(getUInt8AsInt()) 
    } 

    /// Method to get a UTF-8 encoded string preceded by a 2-byte length. 
    public func getMediumString() -> String { 
     return getTextData(getUInt16AsInt()) 
    } 

    /// Method to get a UTF-8 encoded string preceded by a 4-byte length. By convention a length of 
    /// -1 is used to signal a String? value of nil. 
    public func getLongString() -> String? { 
     let encodedLength = getInt32() 
     if encodedLength == -1 { 
     return nil 
     } 
     return getTextData(Int(encodedLength)) 
    } 

    /// Method to get a single byte from the byte array, returning it as an Int. 
    public func getUInt8AsInt() -> Int { 
     return Int(getUInt8()) 
    } 

    /// Method to get a single byte from the byte array. 
    public func getUInt8() -> UInt8 { 
     let returnValue = _byteArray[_arrayIndex] 
     _arrayIndex += 1 
     return returnValue 
    } 

    /// Method to get a UInt16 from two bytes in the byte array (little-endian), returning it as Int. 
    public func getUInt16AsInt() -> Int { 
     return Int(getUInt16()) 
    } 

    /// Method to get a UInt16 from two bytes in the byte array (little-endian). 
    public func getUInt16() -> UInt16 { 
     let returnValue = UInt16(_byteArray[_arrayIndex]) | 
         UInt16(_byteArray[_arrayIndex + 1]) << 8 
     _arrayIndex += 2 
     return returnValue 
    } 

    /// Method to get an Int32 from four bytes in the byte array (little-endian). 
    public func getInt32() -> Int32 { 
     return Int32(bitPattern: getUInt32()) 
    } 

    /// Method to get a UInt32 from four bytes in the byte array (little-endian). 
    public func getUInt32() -> UInt32 { 
     let returnValue = UInt32(_byteArray[_arrayIndex]) | 
         UInt32(_byteArray[_arrayIndex + 1]) << 8 | 
         UInt32(_byteArray[_arrayIndex + 2]) << 16 | 
         UInt32(_byteArray[_arrayIndex + 3]) << 24 
     _arrayIndex += 4 
     return returnValue 
    } 

    // Method to decode UTF-8 encoded text data in the byte array. 
    private func getTextData(_ numberBytes : Int) -> String { 
     if numberBytes == 0 { 
     return "" // Tiny optimization? 
     } 
     let startIndex = _arrayIndex 
     _arrayIndex += numberBytes 
     return String(bytes: _byteArray[startIndex ..< _arrayIndex], encoding: String.Encoding.utf8)! 
    } 
} 

Dies ist ein Ausschnitt aus einer größeren Klasse (siehe auch https://stackoverflow.com/a/41547936/253938), die ich serialisierten Daten zu verarbeiten, verwendet werden.

0

Sie müssen zuerst Int8-Array in Data konvertieren und dann in String konvertieren.

Dies ist meine Lösung:

var buffer = [Int8](repeating: 0, count: 100) 
    let data = Data(bytes: buffer as [Int8], count: buffer.count); 
    return String(data: data, encoding: .utf8) 
0

Swift 4/Ubuntu 16,04

let serverAns = [UInt8](repeating: 0x50, count: 100) 
let readBytes = 8 
let truncatedServerAns = serverAns[0..<readBytes] 
let tsaData = Data(bytes: truncatedServerAns) 
let serverIdStr = String(data: tsaData, encoding: .utf8) 
print("serverIdStr=\(String(describing: serverIdStr))") 

// Prints: 
// serverIdStr=Optional("PPPPPPPP") 
Verwandte Themen