En utilisant les opérateurs sur les bits en C++ pour modifier 4 caractères à int
Ce que je dois faire est d'ouvrir un fichier en mode binaire qui contient des données stockées qui sont destinés à être interprétés comme des nombres entiers. J'ai vu d'autres exemples tels que Stackoverflow-Lecture “integer” taille octets à partir d'un char* tableau. mais je veux essayer de prendre une approche différente (j'ai peut-être juste têtu, ou stupide :/). J'ai d'abord créé un simple fichier binaire dans un éditeur hexadécimal qui se lit comme suit.
00 00 00 47 00 00 00 17 00 00 00 41
Cela (devrait) égal 71, 23 ans, et 65 ans si les 12 octets ont été divisés en 3 entiers.
Après l'ouverture de ce fichier en mode binaire et la lecture de 4 octets dans un tableau de caractères, comment puis-je utiliser les opérations bit à bit pour faire des char[0] bits soit les 8 premiers bits d'un entier (int) et ainsi de suite jusqu'à ce que les bits de chaque char font partie de l'int.
My integer = 00 00 00 00
+ ^ ^ ^ ^
Chars Char[0] Char[1] Char[2] Char[3]
00 00 00 47
So my integer(hex) = 00 00 00 47 = numerical value of 71
Aussi, je ne sais pas comment le boutisme de mon système est en jeu ici, donc, il y a quelque chose que j'ai besoin de garder à l'esprit?
Voici un extrait de code de ce que j'ai à ce jour, je ne sais juste pas les prochaines mesures à prendre.
std::fstream myfile;
myfile.open("C:\\Users\\Jacob\\Desktop\\hextest.txt", std::ios::in | std::ios::out | std::ios::binary);
if(myfile.is_open() == false)
{
std::cout << "Error" << std::endl;
}
char* mychar;
std::cout << myfile.is_open() << std::endl;
mychar = new char[4];
myfile.read(mychar, 4);
Finalement, j'ai un plan sur la façon de traiter avec la lecture de chars à partir d'un fichier et peut-être un type de données personnalisé par la suite, mais d'abord j'ai juste besoin de se familiariser avec l'utilisation des opérations bit à bit.
Merci.
Votre fichier binaire est "big-endian". Donc, tant que vous convertir ses octets pour les entiers dans un big-endian façon, vous n'avez pas besoin de s'inquiéter à propos de l'endianness de l'ordinateur.
...jusqu'à ce que vous déplacez votre code à un autre système, et d'essayer de lire les données à partir d'un big-endian système. Ensuite, vous aurez des problèmes.
Donc David l'appel à
ntohl()
pour éviter celaOriginalL'auteur contrapsych | 2011-03-17
Vous devez vous connecter pour publier un commentaire.
Vous voulez l'opération de bits de décalage vers la gauche de l'opérateur:
Ce qu'il fait est le décalage à gauche de l'argument d'un nombre spécifié de bits vers la gauche, en ajoutant des zéros à partir de la droite comme de la farce. Par exemple,
2 << 1
est de 4, depuis le 2 est10
en binaire et décaler vers la gauche donne100
, qui est de 4.Cela peut être plus écrit dans un cadre plus général forme de boucle:
Le stockage de votre système n'a pas d'importance ici; vous savez le boutisme de la représentation dans le fichier, ce qui est constant (et donc portable), de sorte que lorsque vous lisez dans les octets de savoir quoi faire avec eux. La représentation interne de l'entier de votre CPU/mémoire peut être différent de celui du fichier, mais la logique bit à bit de la manipulation de ce code est indépendant de votre système de stockage; les bits de poids faible sont toujours à la droite, et le plus à gauche (dans le code). C'est pourquoi le déplacement est multi-plateforme -- il fonctionne à l' logique peu le niveau 🙂
Cela fonctionne correctement avec le signe? Ne devriez pas utiliser
unsigned char
?Vous avez tout à fait raison, ce code ne fonctionne pas avec accusé de caractères, car ils sont implicitement converti en
int
de la même (numérique) valeur avant la maj est faite. Je vais ajouter un peu de jette.(24 - i * 8)
nécessite de rappeler la priorité de l'opérateur, et suppose notamment la mise en œuvre définies par les choses. Je préfère((sizeof(unsigned) - i) * CHAR_BITS)
iciAlors que je suis d'accord
CHAR_BITS
est meilleure dans le code de la bibliothèque, par souci de garder l'exemple simple, je pense, en supposant que les 8 bits de caractères est assez sûr; les autres types devait être changé en tant que bien peur qu'ils n'aient <32 bits. Comme pour la priorité de l'opérateur, sûrement, c'est la connaissance commune que la multiplication a une priorité plus élevée que la soustraction? Ce n'est pas spécifique au C++...OriginalL'auteur Cameron
Avez-vous pensé à utiliser Boost.Esprit de faire un binaire analyseur? Vous pourriez frapper un peu d'une courbe d'apprentissage quand vous commencez, mais si vous voulez élargir votre programme plus tard pour lire des flotteurs et des types structurés, vous aurez une excellente base pour commencer.
Esprit est très bien documenté et fait partie de Boost. Une fois que vous obtenez autour de la compréhension de ses tenants et aboutissants, c'est vraiment ahurissant ce que vous pouvez faire avec elle, donc si vous avez un peu de temps pour jouer avec elle, j'aimerais vraiment vous recommandons de prendre un coup d'oeil.
Sinon, si vous voulez que votre binaire pour être "portable" - c'est à dire que vous voulez être en mesure de le lire sur un big-endian et little-endian machine, vous aurez besoin d'une sorte de marque d'ordre d'octet (BOM). Ce serait la première chose que vous aviez lu, après quoi vous pouvez simplement lire votre entiers octet par octet. Chose la plus simple serait probablement de les lire dans un syndicat (si vous connaissez la taille de l'entier que vous allez lire), comme ceci:
lire les données dans la uc_ membre, le swap d'octets si vous avez besoin de changer de stockage et la lecture de la valeur de la ui_ membre. Il n'y a pas de changement, etc. à faire - à l'exception de l'échange si vous voulez changer l'endianness..
HTH
rlc
OriginalL'auteur rlc