Bonjour,
J'ai un tableau de 360 octets et je voudrai convertir tout les 2 octets successives en un entier et les mettre dans un autre tableau qui sera remplie de 180 entiers.
Pouvez vous me proposer un algorithme?
Merci :D
Version imprimable
Bonjour,
J'ai un tableau de 360 octets et je voudrai convertir tout les 2 octets successives en un entier et les mettre dans un autre tableau qui sera remplie de 180 entiers.
Pouvez vous me proposer un algorithme?
Merci :D
Non c'est l'inverse : tu proposes, nous commentons. ;)
Bonjour,
En faite j'ai une trame des données qui contient les différents distances en octet. Donc j'ai besoin de convertir ces distances en entier. Les distances sont codés sur 2 octets successives.
Programme:
char buffer[828];
int tab1[180],tab2[180],i,j=0;
for(i=103;i<=461;i=i+2)
{
tab1[j]=buffer[i]<<8;
tab2[j]=buffer[i+1]<<8;
distance[j]=tab1[j]+tab1[j];
cout<<"tab1["<<j<<"]="<<tab1[j]<<endl;
cout<<"tab2["<<j<<"]="<<tab2[j]<<endl;
cout<<"distance["<<j<<"]="<<distance[j]<<endl;
j=j+1;
}
Remarques :
- :tagcode:
- Pas besoin de créer deux énormes tableaux tab1 et tab2. Pour avoir deux variables intermédiaires, il suffit de créer deux entiers à l'intérieur de la boucle for.
- Dans tab2[j]=buffer[i+1]<<8, il faut enlever <<8.
- Dans le cas particulier où int fait deux octets, alors (255 << 8) + 255 est plus grand que la valeur maximale d'un int => signed overflow => comportement indéterminé. Il vaut mieux utiliser le type unsigned int.
- char peut être signé ou non signé. Ça dépend du compilateur et des options du compilateur. Si on veut un type non signé, on utilise unsigned char.
Proposition de correction :
Si on suppose que distance est un tableau de unsigned int, tu peux alors appeler la fonction ainsi :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <cstddef> // size_t #include <climits> // CHAR_BIT // nombre de bits d'un char, donc quasiment toujours 8 static_assert(sizeof(int) >= 2, "int is too small."); // rq : ne peut pas être faux si CHAR_BIT == 8 void copyPairBytes(unsigned int* dest, const unsigned char* src, size_t count) { for(size_t k = 0; k < count; ++k) { const unsigned int val1 = src[2*k]; const unsigned int val2 = src[2*k+1]; dest[k] = (val1 << CHAR_BIT) + val2; } }
Si tu peux changer le type de buffer en tableau de unsigned char, tu n'auras plus besoin de reinterpret_cast.Code:copyPairBytes(distance, reinterpret_cast<unsigned char*>(buffer)+103, 180);
Bon là tu décales les deux octets, il faut choisir. D'autre part si les endianness-es du buffer et de la machine cible sont identiques, l'opération se résume à un simple memcpy :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include <cstdint> // fixed-width types #include <cstring> // memcpy #include <iostream> #define SRC_ENDIANNESS (__BIG_ENDIAN) #define DST_ENDIANNESS (__BYTE_ORDER) static void concat(uint16_t *dst, const uint8_t *src, std::size_t count) { #if SRC_ENDIANNESS == DST_ENDIANNESS std::memcpy(dst, src, count * 2); #else for(std::size_t i{0}; i <= count; ++i) { const auto i2 = i * 2; dst[i] = (uint16_t(src[i2]) << 8) | (uint16_t(src[i2 + 1]) << 0); } #endif } int main() { const uint8_t src[] = { 0xde, 0xad, 0xbe, 0xef }; uint16_t dst[2]; concat(dst, src, 2); std::cout << std::hex << "{ 0x" << dst[0] << ", 0x" << dst[1] << " }" << std::endl; return 0; }
Tu parles de trame : en règle générale on utilise htons et consorts pour ce genre de tâche.