2009-02-04 13 views
1

Impossible de trouver exactement comment procéder en C/C++.C/C++ lit un octet à partir d'un hexinput à partir de stdin

Entrée: valeurs hexdecimal, par exemple: FFFFFFFFFF ...

J'ai essayé le code suivant pour lire l'entrée:

uint16_t twoBytes; 
scanf("%x",&twoBytes); 

Cest fonctionne très bien et tout, mais comment J'ai divisé les 2bytes en 1bytes uint8_t valeurs (ou peut-être même lire le premier octet seulement). Voudrait lire le premier octet de l'entrée, et le stocker dans une matrice d'octets dans une position de choix.

uint8_t matrix[50][50] 

Depuis que je ne suis pas très habile dans formating/lecture de l'entrée en C/C++ (et ne l'ai utilisé scanf jusqu'à présent) d'autres idées sur la façon de le faire facilement (et rapidement si elle va) est très appréciée . Edit: Trouvé encore une meilleure méthode en utilisant la fonction fread car elle permet de spécifier combien d'octets il devrait lire dans le flux (stdin dans ce cas) et enregistrer dans une variable/tableau.

size_t fread (void * ptr, size_t size, size_t count, FILE * stream); 

Paramètres

ptr - pointeur vers un bloc de mémoire d'une taille minimale de la taille (count *) octets.

size - Taille en octets de chaque élément à lire.

count - Nombre d'éléments, chacun d'une taille d'octets taille. Stream - Pointeur vers un objet FILE qui spécifie un flux d'entrée.

cplusplus ref

Répondre

2

%x lit un unsigned int, pas uint16_t (pensé qu'ils peuvent être les mêmes sur votre plateforme).

Pour lire un seul octet, essayez ceci:

uint32_t byteTmp; 
scanf("%2x", &byteTmp); 
uint8_t byte = byteTmp; 

Ce lit un unsigned int, mais arrête après avoir lu deux caractères (deux caractères hexadécimaux est égal à huit bits ou un octet).

+0

Cela fonctionnera probablement sur une machine little-endian, mais cela ne fonctionnera pas sur une machine big-endian. Vous voulez utiliser "% hhx" à la place. –

+0

@Rosenfield, Ah, j'ai oublié cela en écrivant ma réponse (mais je l'ai considéré en y pensant). De plus, le modificateur hh n'est pas standard (spécifique à GCC). – strager

+0

Je ne pense toujours pas que l'endianisme soit un problème. Lorsque vous faites toutes ces opérations, le compilateur est assez intelligent pour traiter byteTmp comme un seul nombre, pas comme 4 octets, donc quand vous lisez dedans, vous obtenez un nombre de 1 octet mis dans une valeur de 4 octets, ça va bien. Quand vous lancez, il prend les bons bits. –

0

Vous devriez être en mesure de diviser la variable comme ceci:

uint8_t LowerByte=twoBytes & 256; 
uint8_t HigherByte=twoBytes >> 8; 
+0

Vous pouvez avoir des problèmes endian là-bas. – strager

+0

Peu probable, parce que les nombres sont des nombres, toujours gros à gauche. Les problèmes endiens ne se produisent que lorsque vous avez un bitstream que vous devez interpréter ... –

+0

En fait, ceci est intéressant: si l'endianness du texte et l'endianness du système différaient, deux Bytes seraient permutés lors de la lecture du flux, mais ensuite LowerByte et highByte être correct car les octets sont de nouveau échangés. Je préférerais jouer la sécurité, cependant, et ne vous inquiétez pas à ce sujet. – strager

0

Quelques pensées:

1) lire sous forme de caractères et de le convertir manuellement - douloureux

2) vous savez qu'il y a un multiple de 4 hexits, vous pouvez juste lire en deux octets puis convertir en valeurs d'un octet avec high = twobytes < < 8; faible = deux fois & FF;

3)% 2x

+0

vous vouliez probablement haut = deux bits >> 8 –

+0

Je suis dyslexique. J'ai un permis ... –

+0

Ou vous avez des problèmes d'endian ;-) –

1

Merci pour les réponses et commentaires.

La solution la plus simple semble être d'utiliser le format scanf et hhx. Le lire comme deux octets, puis masquer et déplacer semble être une alternative, mais c'est un travail supplémentaire là-bas (même si ce n'est probablement pas perceptible).

Merci encore une fois! "% 2x" attend toujours un entier non signé, donc votre code a un comportement indéfini