C – unsigned int to unsigned conversion de tableau de caractères

J’ai un nombre entier non signé (2 octets) et je veux le convertir en type de caractère non signé. De ma recherche, je trouve que la plupart des gens recommandent de faire ce qui suit:

unsigned int x; ... unsigned char ch = (unsigned char)x; 

Est-ce la bonne approche? Je demande parce que le caractère non signé est de 1 octet et que nous avons converti les données de 2 octets en 1 octet.

Pour éviter toute perte de données, je souhaite créer un tableau de unsigned char [] et enregistrer les octets individuels dans le tableau. Je suis coincé à ce qui suit:

  unsigned char ch[2]; unsigned int num = 272; for(i=0; i<2; i++){ // how should the individual bytes from num be saved in ch[0] and ch[1] ?? } 

Aussi, comment pourrions-nous reconvertir le caractère non signé [2] en non signé int .

Merci beaucoup.

Vous pouvez utiliser memcpy dans ce cas:

 memcpy(ch, (char*)&num, 2); /* although sizeof(int) would be better */ 

De plus, comment serait converti le caractère non signé [2] en non signé int.

De la même manière, il suffit d’inverser les arguments de memcpy.

Que diriez-vous:

 ch[0] = num & 0xFF; ch[1] = (num >> 8) & 0xFF; 

L’opération inverse est laissée comme un exercice.

Pourquoi ne pas utiliser un syndicat?

 union { unsigned int num; unsigned char ch[2]; } theValue; theValue.num = 272; printf("The two bytes: %d and %d\n", theValue.ch[0], theValue.ch[1]); 

Cela dépend vraiment de votre objective: pourquoi voulez-vous convertir cela en un personnage unsigned char ? Selon la réponse à cette question, il existe différentes manières de procéder:

  • Truncate : C’est ce qui a été recommandé. Si vous essayez simplement de compresser des données dans une fonction nécessitant un caractère unsigned char , uchar ch = (uchar)x simplement uchar ch = (uchar)x (mais, bien sûr, méfiez-vous de ce qui se passe si votre int est trop grand).

  • Endian spécifique : Utilisez cette option lorsque votre destination requirejs un format spécifique. Généralement, le code de réseau aime tout ce qui est converti en tableaux de caractères big endian:

     int n = sizeof x; for(int y=0; n-->0; y++) ch[y] = (x>>(n*8))&0xff; 

    Will le fait.

  • Machine Endian . Utilisez-le lorsqu’il n’y a pas d’exigence d’endianité et que les données ne seront disponibles que sur une seule machine. L’ordre du tableau changera d’une architecture à l’autre. Les gens s’occupent généralement de cela avec les union :

     union {int x; char ch[sizeof (int)];} u; ux = 0xf00 //use u.ch 

    avec memcpy :

     uchar ch[sizeof(int)]; memcpy(&ch, &x, sizeof x); 

    ou avec le casting simple toujours dangereux (qui est un comportement indéfini, et se bloque sur de nombreux systèmes):

     char *ch = (unsigned char *)&x; 

Bien entendu, un tableau de caractères suffisamment grand pour contenir une valeur plus grande doit être exactement aussi grand que cette valeur elle-même. Donc, vous pouvez simplement prétendre que cette valeur plus grande est déjà un tableau de caractères:

 unsigned int x = 12345678;//well, it should be just 1234. unsigned char* pChars; pChars = (unsigned char*) &x; pChars[0];//one byte is here pChars[1];//another byte here 

(Une fois que vous comprenez ce qui se passe, vous pouvez le faire sans aucune variable, tout simplement un casting)

Vous devez juste extraire ces octets en utilisant bitwise & operator . OxFF est un masque hexadécimal permettant d’extraire un octet. Veuillez regarder les différentes opérations de bits ici – http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/

Un exemple de programme est le suivant:

 #include  int main() { unsigned int i = 0x1122; unsigned char c[2]; c[0] = i & 0xFF; c[1] = (i>>8) & 0xFF; printf("c[0] = %x \n", c[0]); printf("c[1] = %x \n", c[1]); printf("i = %x \n", i); return 0; } 

Sortie:

 $ gcc 1.c $ ./a.out c[0] = 22 c[1] = 11 i = 1122 $