44 votes

Ruby: créer une chaîne à partir d'octets

Je voudrais construire une chaîne à partir d'une valeur d'octet.

Actuellement, j'utilise :

str = " "
str[0] = byte

Cela semble fonctionner correctement mais je trouve cela laid et peu évolutif pour des chaînes de caractères de plus de 1 caractère.

Une idée ?

69voto

Jason Watkins Points 1960

Il y a une approche beaucoup plus simple que celles mentionnées ci-dessus : Array#pack:

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

Je crois que pack est implémenté en c dans Ruby de Matz, donc il sera également considérablement plus rapide avec de très grands tableaux.

De plus, pack peut gérer correctement l'UTF-8 en utilisant le modèle 'U*'.

0 votes

Cette réponse décrit la bonne façon de le faire. Mais n'oubliez pas de définir correctement l'encodage en Ruby 1.9, comme le souligne la réponse de Grosser!

9 votes

Tu as eu de la 'chance' avec le c* en minuscule. Tu veux vraiment C*. Voir : ruby-doc.org/core-1.9.3/Array.html c c'est pour "caractère signé sur 8 bits (char signé)", C c'est pour "caractère non signé sur 8 bits (char non signé)"

5 votes

Le Pack NE peut PAS gérer correctement l'UTF-8 en utilisant le modèle "U*". C'est incorrect. "U*" emballe un tableau de points de code Unicode, pas des octets UTF8.

21voto

grosser Points 4300

Pour 1.9 vous avez besoin :

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

10 votes

Je recommande d'utiliser C* car vous voulez des entiers non signés. c* est pour les entiers signés. Notez que: "ä".unpack('c*') == [-61, -92]. Ce que vous voulez est: "ä".unpack('C*') == [195, 164]

10voto

動靜能量 Points 33008

Ne peut pas se rappeler s'il existe une seule fonction qui fait cela:

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

0 votes

Sympa, je ne savais pas pour la méthode chr

0 votes

@VincentRobert Comment pouvez-vous / pouvez-vous faire cet exemple dans ce style? [195,164].pack('c*').force_encoding('UTF-8')

0 votes

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

4voto

hyperlogic Points 2343

Si bytes est un tableau de Fixnum's vous pourriez essayer ceci :

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

ou ceci :

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

0voto

David Hempy Points 1199

Ce n'est pas la question de l'OP, mais si vous avez juste un seul octet (pas dans un tableau) et que vous voulez en faire une chaîne, utilisez chr

c = 65
=> 65
c.chr
=> "A"
c.chr.class
=> String

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X