web-dev-qa-db-ja.com

C-unsigned intからunsigned char配列への変換

符号なし整数(2バイト)があり、それを符号なしchar型に変換したい。私の検索から、ほとんどの人が次のことを行うことを推奨していることがわかりました。

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

適切なアプローチですか? unsigned charは1バイトであり、2バイトのデータから1バイトにキャストしたためです。

データの損失を防ぐために、unsigned char []の配列を作成し、個々のバイトを配列に保存します。私は次のことにこだわっています。

 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] ??
 }

また、nsigned char [2]をunsigned intに戻す方法

どうもありがとう。

16
Jake

その場合、memcpyを使用できます。

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

また、どのようにunsigned char [2]をunsigned intに変換するか。

同様に、memcpyの引数を逆にするだけです。

19
jpalecek

どうですか:

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

逆の操作は演習として残します。

17
cnicutar

ユニオンを使用してはどうですか?

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]);
7
abelenky

それは本当にあなたの目標に依存します:なぜこれを_unsigned char_に変換したいのですか?その答えに応じて、これを行うためのいくつかの異なる方法があります。

  • 切り捨て:これが推奨されたものです。 _unsigned char_を必要とする関数にデータを絞り込もうとしている場合は、単にuchar ch = (uchar)xをキャストします(もちろん、intが大きすぎると何が起こるかに注意してください)。

  • 特定のエンディアン:宛先に特定の形式が必要な場合に使用します。通常、ネットワーキングコードは、すべてがビッグエンディアンのchar配列に変換されることを好みます。

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

    それをします。

  • マシンエンディアン。エンディアンの要件がなく、データが1台のマシンでのみ発生する場合に使用します。配列の順序は、アーキテクチャごとに異なります。通常、これはunionsで処理します。

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

    memcpyを使用:

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

    または、常に危険な単純なキャスト(未定義の動作であり、多数のシステムでクラッシュします):

    _char *ch = (unsigned char *)&x;
    _
6
Dave

もちろん、より大きな値を含むのに十分な大きさのcharの配列は、この値自体とまったく同じ大きさでなければなりません。したがって、この大きな値がすでにcharの配列であると単純にふりをすることができます。

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

(何が起こっているのかを理解したら、変数なしで行うことができ、すべてキャストするだけです)

4
Agent_L

bitwise & operatorを使用してこれらのバイトを抽出するだけです。 OxFFは、1バイトを抽出するための16進マスクです。ここでさまざまなビット操作を見てください- http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/

サンプルプログラムは次のとおりです。

#include <stdio.h>

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;
}

出力:

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