7
votes

À Perl, puis-je traiter une chaîne comme une matrice d'octet?

en Perl, est-il approprié d'utiliser une chaîne sous forme de tableau d'octets contenant des données 8 bits? Toute la documentation que je peux trouver sur ce sujet se concentre sur des chaînes de 7 bits.

Par exemple, si je lis des données d'un fichier binaire dans $ données xxx < / Pré>

Et je veux obtenir le premier octet, est substr ($ données, 1,1) approprié? (Encore une fois, en supposant que ce soit des données de 8 bits)

Je viens d'un arrière-plan C principalement et je suis habitué à adopter un pointeur char sur un Lire () fonction. Mon problème pourrait être que je ne comprends pas quelle est la représentation sous-jacente d'une chaîne dans Perl.


0 commentaires

6 Réponses :


1
votes

Vous voulez probablement utiliser SYSOPEN et SYSRead Si vous souhaitez lire des octets à partir de fichier binaire.

Voir aussi perlopentut .

si cela est approprié ou nécessaire dépend de ce que vous essayez exactement de faire. < / p> xxx

sortie: xxx


0 commentaires

6
votes

La documentation groupée pour la commande lisez , reproduit ici, fournit de nombreuses informations pertinentes pour votre question.

lecture de fichiersHandle, scalaire, longueur, décalage

lecture de fichiersHandle, scalaire, longueur

tentative de lecture de longueur caractères de données dans scalaire variable à partir du fichier de fichier spécifié. Renvoie le nombre de caractères lisent réellement, 0 à la fin du fichier, ou undef s'il existe était une erreur (dans ce dernier cas $! est également défini). Scalaire va être cultivé ou rétréci de sorte que le dernier personnage lu réellement est le dernier caractère du scalaire après la lecture.

Un décalage peut être spécifié pour placer les données de lecture à un endroit dans la corde autre que le début. Un décalage négatif Spécifie le placement à ce nombre de caractères comptant à l'envers à partir de la fin de la chaîne. Un décalage positif supérieur à la Longueur du scalaire Résultats dans la chaîne étant rembourrée au taille requise avec des octets "\ 0" avant le résultat de la lecture annexé.

L'appel est réellement mis en œuvre en termes de Perl ou de Fread de System () Appelez. Pour obtenir un véritable appel (2) appel système, voir "SysRead".

Notez les caractères : en fonction de l'état du fichierHandle, Les octets ou les caractères (8 bits) sont lus. par défaut tout Les titres de fichiers fonctionnent sur des octets, mais par exemple si le fichierHandle a été ouvert avec la couche d'E / S ": UTF8" (voir "Ouvrir", et le "Ouvrir" pragma, ouvert), l'E / S fonctionnera sur UTF-8 codé Personnages Unicode, non octets. De même pour le ": codage" Pragma: Dans ce cas, tous les caractères peuvent être lus.


3 commentaires

Ma nature étant très pédant, quand je lisais ceci dans la documentation que j'ai trouvée caractère ambigu. Je n'étais pas clair si cela signifie une unité de données (c.-à-d. Un octet) ou une unité d'une chaîne (dépendante du codage)


Appeler fichier binmode, ": brut" ou fichier binmod, ": octets" ouvrira toujours votre geste de fichier dans "octets", quelle que soit votre couche IO par défaut (disons, Si vous avez déclaré utiliser utf8 ).


En fait, je suis d'accord que l'utilisation de "personnages" se lit comme un bug pour moi, en particulier à la manière dont l'attention est portée à la distinction entre les caractères, les octets et les octets dans Encode (3perl) . Il s'agit d'être le bon mot, mais je pense que je l'aimerais si cela indique "des caractères (tels que définis par la couche d'E / S actuelle)". Je suppose que c'est aussi une critique de votre réponse, dans la mesure où lue lit toujours "caractères" - mais parfois "caractère" est défini comme "octet" et parfois comme "point de code UTF-8".



2
votes

voir PACLAC -F Pack et Perldoc -f Déballez pour traiter des chaînes en tant que réseaux d'octets.


0 commentaires

0
votes

Cela pourrait aider davantage si vous nous dites ce que vous essayez de faire avec le tableau d'octets. Il existe différentes façons de travailler avec des données binaires et chacun se prête à un ensemble d'outils différents.

Voulez-vous convertir les données en une matrice PERL? Si oui, pack et Déballez sont un bon début. Split pourrait également être utile.

Voulez-vous accéder aux éléments individuels de la chaîne sans le déballer? Si tel est le cas, substr est rapide et fera le truc sur 8 données d'octets. Si vous voulez d'autres profondeurs de bits, jetez un coup d'œil à la fonction VEC , qui marchait une chaîne sous forme de vecteur de bit.

Voulez-vous scanner la chaîne et convertir certains octets vers d'autres octets? Ensuite, le s /// ou tr /// peut être utile.


0 commentaires

0
votes

Permettez-moi simplement de poster un petit exemple sur le traitement de la chaîne comme une matrice binaire - car j'ai moi-même trouvé difficile de croire que quelque chose appelé "substr" traiterait des octets nuls; Mais semble-t-il, ci-dessous est un extrait d'une session de terminal de débogueur Perl (avec des approches de chaîne et de tableau / liste): xxx


0 commentaires

1
votes

Les chaînes sont des chaînes de "caractères", qui sont plus grandes qu'un octet. 1 Vous pouvez stocker des octets En eux et les manipuler comme si elles sont des personnages, prenant substr code> S d'eux et ainsi de suite, et aussi longtemps que vous manipulez simplement des entités en mémoire, tout est assez pêchy. Le stockage des données est étrange, mais c'est surtout votre problème. 2

lorsque vous essayez de lire et Écrivez des fichiers, le fait que vos personnages puissent ne pas mapper les octets devient important et intéressant. Ne pas mentionner ennuyeux. Cette gêne est en fait faite un peu pire par Perl essayant de faire ce que vous voulez dans le cas commun: si tous les caractères de la chaîne entrent dans un octet et que vous vous trouviez sur un système d'exploitation non Windows, vous n'avez pas réellement faire quelque chose de spécial pour lire et écrire des octets. Cependant, Perl se plaint si vous avez stocké un personnage de taille non octets et tentera de l'écrire sans lui donner un indice sur ce qu'il faut faire avec cela. P>

Ceci est un peu lointain de loin, largement Parce que le codage est un sujet important et déroutant. Laissez-moi le laisser là-bas avec quelques références: regardez Encode (3perl) , ouvert (3perl) , Perldoc Open et Perldoc BinMode pour beaucoup de hilarants et de gory Détails. P>

La réponse résumée est donc "Oui, vous pouvez traiter des chaînes comme si elles contiennent des octets si elles contiennent en fait des octets, que vous pouvez assurer uniquement en lecture et en écriture d'octets.". P >

1 : ou pédaniquement, "qui peut exprimer une plus grande gamme de valeurs qu'un octet, bien que Ils sont stockés comme des octets quand cela est pratique ". Je pense. P>

2 : Pour l'enregistrement, les chaînes de Perl sont représentées en interne par Une structure de données appelée «PV» qui, en plus d'un pointeur de caractères, sait que la longueur de la chaîne et la valeur actuelle de POS code>. 3 p>

3 : Eh bien, il commencera à stocker la valeur actuelle de POS code> s'il commence à être intéressant. Voir aussi P>

use Devel::Peek;

my $x = "bluh bluh bluh bluh";
Dump($x);
$x =~ /bluh/mg;
Dump($x);
$x =~ /bluh/mg;
Dump($x);


0 commentaires