2009-06-06 18 views
36

Vorrei costruire una stringa da un valore di byte.Ruby: crea una stringa da byte

Attualmente uso:

str = " " 
str[0] = byte 

Questo sembra funzionare bene ma trovo brutto e non molto scalabile per le stringhe più lunghe di 1 carattere.

Qualche idea?

risposta

51

C'è un approccio molto più semplice di uno dei precedenti: Array#pack:

>> [65,66,67,68,69].pack('c*') 
=> "ABCDE" 

Credo che il pacchetto sia implementato in c in ruby ​​matz, quindi sarà anche molto più veloce con array molto grandi.

Inoltre, il pacchetto può gestire correttamente UTF-8 utilizzando il modello 'U *'.

+0

Questa risposta descrive il modo corretto per farlo. Ma ricordati di impostare correttamente la codifica in Ruby 1.9 come indica la risposta di Grosser! – severin

+8

Hai 'fortunato' con il 'c minuscolo ''. Tu vuoi veramente 'C *'. Vedi: http://www.ruby-doc.org/core-1.9.3/Array.html 'c' è per" 8-bit signed (signed char) ",' C' è per "8-bit unsigned (char unsigned) "Il pacchetto –

+4

NON può gestire correttamente UTF-8 utilizzando il modello" U * ". Questo non è corretto "U *" include una serie di codepoint Unicode, non byte UTF8. – stephenjudkins

3

Se byte è un array di Fixnum vi potrebbe provare questo:

bytes.map {|num| num.chr}.join 

o questo:

s = '' 
bytes.each {|i| s << i} 
5

non ricordo se v'è una singola funzione che lo fa:

>> a = [65,66,67] 
=> [65, 66, 67] 
>> a.map {|x| x.chr}.join 
=> "ABC" 
+0

Nizza, non sapevano sul metodo chr –

+0

@VincentRobert Come si può/si può fare questo esempio in quello stile? '[195,164] .pack ('c *'). Force_encoding ('UTF-8')' –

+0

Ottenuto: '[195,164] .map {| x | x.chr} .join.force_encoding ('UTF-8') ' –

15

per 1,9 è necessario:

[195,164].pack('c*').force_encoding('UTF-8') 
+8

Io raccomando di usare 'C *' perché vuoi numeri interi senza segno. 'c *' è per interi con segno. Nota: '" ä ".unpack ('c *')' == '[-61, -92]'. Quello che vuoi è: '" ä ".unpack ('C *')' == '[195, 164]' –