2010-06-01 8 views
3

I ont une variable à court entier appelé s_int qui contient value = 2copie d'un short int à un tableau de caractères

unsighed short s_int = 2; 

Je veux copier ce numéro à un tableau de caractères à la première et la deuxième position d'un caractère tableau. Nous supposons que nous avons char buffer[10];. Nous voulons que les deux octets de s_int soient copiés à buffer[0] et buffer[1].

Comment puis-je le faire?

Répondre

10

La manière habituelle de faire serait avec les opérateurs de bits pour couper et couper en dés, un octet à la fois:

b[0] = si & 0xff; 
b[1] = (si >> 8) & 0xff; 

bien que cela devrait vraiment être fait dans un unsigned char, pas une char plaine comme ils sont signés sur la plupart des systèmes.

Le stockage d'entiers plus grands peut être effectué de la même manière ou avec une boucle.

+0

Quelle est la raison de '& 0xff'? – Almir

+0

Il transforme la troncature implicite en une explicite. En d'autres termes, l'intention du programmeur est claire. (Je pense que certains compilateurs pourraient se plaindre à ce sujet?) – crazyscot

+0

oh, je comprends :) thanx – Almir

0

Si vous ne voulez pas faire ce genre de choses que vous pourriez bitwise effectuer les opérations suivantes

char* where = (char*)malloc(10); 
short int a = 25232; 
where[0] = *((char*)(&a) + 0); 
where[1] = *((char*)(&a) + 1); 
6

*((short*)buffer) = s_int;

Mais viator emptor que l'ordre des octets résultant variera en fonction boutisme.

+0

Bingo. Facile et évident. –

+1

AKA rapide et sale;) – James

+0

gcc pourrait vous dire, 'l'utilisation des expressions de fonte comme lvalues ​​est dépréciée'. –

3

À l'aide de pointeurs et de moulages.

unsigned short s_int = 2; 
unsigned char buffer[sizeof(unsigned short)]; 

// 1. 
unsigned char * p_int = (unsigned char *)&s_int; 
buffer[0] = p_int[0]; 
buffer[1] = p_int[1]; 

// 2. 
memcpy(buffer, (unsigned char *)&s_int, sizeof(unsigned short)); 

// 3. 
std::copy((unsigned char *)&s_int, 
      ((unsigned char *)&s_int) + sizeof(unsigned short), 
      buffer); 

// 4. 
unsigned short * p_buffer = (unsigned short *)(buffer); // May have alignment issues 
*p_buffer = s_int; 

// 5. 
union Not_To_Use 
{ 
    unsigned short s_int; 
    unsigned char buffer[2]; 
}; 

union Not_To_Use converter; 
converter.s_int = s_int; 
buffer[0] = converter.buffer[0]; 
buffer[1] = converter.buffer[1]; 
2

je serais memcpy, quelque chose comme

memcpy(buffer, &s_int, 2);

Le boutisme est conservé correctement de sorte que si vous lancez tampon en bref * non signé, vous pouvez lire la même valeur de s_int la bonne façon. L'autre solution doit être endian-aware ou vous pouvez permuter lsb et msb. Et bien sûr sizeof (short) doit être 2.

+1

Le 'memcpy()' est une bonne approche, mais notez que "préserver l'endianness" n'est pas toujours correct. La réponse de crazyscot met la réponse dans le tampon avec une endianness * connue *, ce qui est souvent ce qui est vraiment nécessaire (par exemple, si le tampon doit être sauvegardé dans un fichier ou envoyé sur un réseau). Votre réponse met la réponse dans le tampon avec l'endianness * host *, qui est aussi parfois ce qui est nécessaire (mais moins souvent). – caf

+0

oui bien sûr: avec "endiannes est préservé" Je voulais dire que les données sont stockées dans le tampon de la même manière qu'un court est conservé en mémoire, permettant un accès direct à la valeur courte du tampon, à condition que l'utilisateur n'a pas besoin pour changer l'endianness en quelque chose de spécifique. – ShinTakezou

+0

Notez cependant que l'accès direct au court-circuit à partir du tampon n'est possible que si le tampon est correctement aligné pour un tel accès; En général, si vous voulez y accéder directement en tant que raccourci, vous devriez l'avoir déclaré en tant que 'struct' contenant un membre' short' plutôt qu'un tableau de 'char'. – caf