web-dev-qa-db-ja.com

CでバイトをInt / uintに変換する

符号なしchar配列[248]があります。バイトでいっぱい。 2F AF FF 00 EB AB CD EFのように.....この配列は、UART(RS232)からのデータをバッファーとして保存するバイトストリームです。

次に、バイトをuint16およびint32に変換して戻します。

C#では、BitConverterクラスを使用してこれを行いました。例えば:

byte[] Array = { 0A, AB, CD, 25 };
int myint1 = BitConverter.ToInt32(bytes, 0);
int myint2 = BitConverter.ToInt32(bytes, 4);
int myint3 = BitConverter.ToInt32(bytes, 8);
int myint4 = BitConverter.ToInt32(bytes, 12);
//...
enter code here
Console.WriteLine("int: {0}", myint1); //output Data...

Cに類似した関数はありますか? (コードはマイクロコントローラで実行されているため、.netではなく、KEILコンパイラを使用しています)

よろしくサム

13
Sam

はいあります。バイトが次の場所にあると仮定します。

uint8_t bytes[N] = { /* whatever */ };

16ビット整数は、連結された2つの8ビット整数であることがわかっています。つまり、256の倍数を持っているか、8だけシフトされています。

uint16_t sixteen[N/2];

for (i = 0; i < N; i += 2)
    sixteen[i/2] = bytes[i] | (uint16_t)bytes[i+1] << 8;
             // assuming you have read your bytes little-endian

同様に32ビットの場合:

uint32_t thirty_two[N/4];

for (i = 0; i < N; i += 4)
    thirty_two[i/4] = bytes[i] | (uint32_t)bytes[i+1] << 8
        | (uint32_t)bytes[i+2] << 16 | (uint32_t)bytes[i+3] << 24;
             // same assumption

バイトがビッグエンディアンで読み取られる場合、もちろん順序を逆にします:

bytes[i+1] | (uint16_t)bytes[i] << 8

そして

bytes[i+3] | (uint32_t)bytes[i+2] << 8
    | (uint32_t)bytes[i+1] << 16 | (uint32_t)bytes[i] << 24

格納されている整数のエンディアンと実行中のアーキテクチャのエンディアンとの間には違いがあることに注意してください。この回答で参照されるエンディアンは、格納された整数、つまりbytesの内容です。 シフト時にエンディアンが考慮される であるため、ソリューションは実行中のアーキテクチャのエンディアンに依存しません。

12
Shahbaz

Cでそれを行うための標準関数はありません。バイトを自分で16ビットおよび32ビット整数に戻す必要があります。エンディアンに注意してください!

次に、単純なリトルエンディアンの例を示します。

extern uint8_t *bytes;
uint32_t myInt1 = bytes[0] + (bytes[1] << 8) + (bytes[2] << 16) + (bytes[3] << 24);

ビッグエンディアンシステムの場合、逆の順序になります。

uint32_t myInt1 = (bytes[0] << 24) + (bytes[1] << 16) + (bytes[2] << 8) + bytes[3];

あなたはで逃げることができるかもしれません:

uint32_t myInt1 = *(uint32_t *)bytes;

アライメントの問題に注意している場合。

20
Carl Norum

リトルエンディアンの場合、memcpyを使用することはできませんか?

memcpy((char*)&myint1, aesData.inputData[startindex], length);
1
Sven Depoorter
            char letter = 'A';
            size_t filter = letter;
            filter = (filter <<  8 | filter);
            filter = (filter << 16 | filter);
            filter = (filter << 32 | filter);
            printf("filter: %#I64x \n", filter); 

結果: "フィルター:0x4141414141414141"

0
Andre