web-dev-qa-db-ja.com

Cでintを2バイトの16進数値に変換する

Cのchar配列に格納するには、intを2バイトの16進値に変換する必要があります。これを行うにはどうすればよいですか?

23
MBU

ライブラリ関数の使用が許可されている場合:

int x = SOME_INTEGER;
char res[5]; /* two bytes of hex = 4 characters, plus NULL terminator */

if (x <= 0xFFFF)
{
    sprintf(&res[0], "%04x", x);
}

整数には4桁を超える16進数のデータが含まれている可能性があるため、最初にチェックを行います。

ライブラリ関数の使用が許可されていない場合は、手動でニブルに分割します。

#define TO_HEX(i) (i <= 9 ? '0' + i : 'A' - 10 + i)

int x = SOME_INTEGER;
char res[5];

if (x <= 0xFFFF)
{
    res[0] = TO_HEX(((x & 0xF000) >> 12));   
    res[1] = TO_HEX(((x & 0x0F00) >> 8));
    res[2] = TO_HEX(((x & 0x00F0) >> 4));
    res[3] = TO_HEX((x & 0x000F));
    res[4] = '\0';
}
34
Vicky

Intが32ビットであると仮定します。

最も簡単な方法:sprintf()を使用するだけ

int intval = /*your value*/
char hexval[5];
sprintf(hexval,"%0x",intval);

Hexval [0]〜hexval [3]を使用してください。 nullで終了する文字列として使用する場合は、hexval[4]=0;を追加します

4
slashmais
_char s[5];  // 4 chars + '\0'
int x = 4660;
sprintf(s, "%04X", x);
_

おそらく、sprintf()のドキュメントを確認する必要があります。このコードは安全ではないことに注意してください。 xが_0xFFFF_より大きい場合、最終的な文字列は4文字を超え、収まりません。より安全にするために、snprintf()を見てください。

3

通常、他の人が推奨するsprintfベースのソリューションを使用することをお勧めします。しかし、何十億ものアイテムを16進数に変換する必要があるツールを作成したとき、sprintfは遅すぎました。そのアプリケーションでは、バイトを文字列にマップする256要素の配列を使用しました。

これは1バイトを変換するための不完全なソリューションです。境界チェックを追加することを忘れないでください。また、配列が静的またはグローバルであることを確認してください。チェックごとに再作成すると、パフォーマンスが低下します。

static const char hexvals[][3]= {"00", "01", "02", ... "FD", "FE", "FF"};
const char *byteStr = hexvals[number];
2
mikerobi

私がテストした簡単な方法を見つけ、それが機能しました。

int value = 11;

array[0] = value >> 8;
array[1] = value & 0xff;

printf("%x%x", array[0], array[1]);

結果は:

000B

これは16進数で11です。

2
MBU

sprintfではなくsnprintfを使用することをお勧めします。

#include <stdio.h>

int main()
{
    char output[5];
    snprintf(output,5,"%04x",255);

    printf("%s\n",output);
    return 0;
}

より安全で、ほとんどすべてのコンパイラで使用できます。

1
MAK
void intToHex(int intnumber, char *txt)
{    
    unsigned char _s4='0';
    char i=4;
    //intnumber=0xffff;

    do {
        i--;
        _s4 = (unsigned char)  ((intnumber >> i*4 ) & 0x000f);
        if(_s4<10)
            _s4=_s4+48;
        else
            _s4=_s4+55;

        *txt++= _s4;    
    } while(i);     
}
...
char text [5]={0,0,0,0,0};
...

intToHex(65534,text);
USART_Write_Text(text);
....
1
cooxee

上記のヴィッキーの答えを使用して

typedef unsigned    long    ulong;
typedef unsigned    char    uchar;

#define TO_HEX(i)   (i <= 9 ? '0' + i : 'A' - 10 + i)
#define max_strhex  (sizeof(ulong)*2)

public uchar
*mStrhex(uchar *p, ulong w, ulong n)
{
    ulong i = 0xF;                                  // index
    ulong mask  = i << (((sizeof(ulong)*2)-1)*4);   // max mask (32 bit ulong mask = 0xF0000000, 16 bit ulong mask = 0xF000)
    ulong shift = (w*4);                            // set up shift to isolate the highest nibble
    if(!w || w > max_strhex)                        // no bold params
        return p;                                   // do nothing for the rebel
    mask  = mask >> (max_strhex-w)*4;               // setup mask to extract hex nibbles
    for(i = 0; i < w; i++){                         // loop and add w nibbles
        shift = shift - 4;                          // hint: start mask for four bit hex is 0xF000, shift is 32, mask >> 32 is 0x0000, mask >> 28 is 0x000F.
        *p++ = TO_HEX(((n & mask) >> shift));       // isolate digit and make hex
        mask = mask >> 4;                           //
        *p = '\0';                                  // be Nice to silly people
    }                                               //
    return p;                                       // point to null, allow concatenation
}
0
10SecTom

これらの答えのほとんどは素晴らしいです、私が追加したいことが1つだけあります:sizeofを使用して正しいバイト数を安全に予約できます。各バイトは最大2桁の16進数(255-> ff)をとることができるため、1バイトあたり2文字です。この例では、「0x」接頭辞に2文字、末尾のNULに1文字を追加します。

int bar; 
// ...
char foo[sizeof(bar) * 2 + 3];
sprintf(foo, "0x%x", bar);
0
Joe Valenzuela

16進数の動的固定長の場合

string makeFixedLengthHex(const int i, const int length)
{
    std::ostringstream ostr;
    std::stringstream stream;
    stream << std::hex << i;
    ostr << std::setfill('0') << std::setw(length) << stream.str();
    return ostr.str();
}

しかし、あなたがそれを自分で処理しなければならないという否定的です。

0
Md. Yusuf

あなたはこれを使用することができ、それは変換するのが簡単で簡単です

typedef union {
    struct hex{
            unsigned  char a;
            unsigned  char b;

    }hex_da;
    short int dec_val;
}hex2dec;

hex2dec value;
value.dec_val=10;

これで、hex値がhex_da構造体に格納され、さらに使用するためにアクセスします。

0
manikanta

おそらく次のようなことを試してください:

void IntToHex(int value, char* buffer) {
  int a = value&16;
  int b = (value>>4)&16;
  buffer[0] = (a<10)?'0'+a:'A'-(a-10);
  buffer[1] = (b<10)?'0'+b:'A'-(b-10);
}
0

この機能は魅力のように機能します。

void Word2WBYTE(BYTE WBYTE[2], Word Value) { 
    BYTE tmpByte[2]; 
    // Converts a value from Word to Word byte ----
    memcpy(tmpByte, (BYTE*) & Value, 2); 
    WBYTE[1] = tmpByte[0]; 
    WBYTE[0] = tmpByte[1]; 
} 

以下を仮定します:

typedef unsigned char   BYTE; 
typedef unsigned short  Word;

使用例:

これを達成したい:

integer = 92
byte array in hex:
a[0] = 0x00;
a[1] = 0x5c;

unsigned char _byteHex[2];
Word2WBYTE(_byteHex, 92);

これは大まかな方法​​です。 ASCII値のエンコーディングが連続していると信頼できない場合は、charに16進値のマッピングを作成するだけです。おそらく、最適化、片付け、きれいにすることができます。また、最後の32ビット== 4の16進文字のキャプチャのみを確認することも想定しています。

#include <stdlib.h>
#include <stdio.h>

#define BUFLEN 5

int main(int argc, char* argv[])
{
  int n, i, cn;
  char c, buf[5];
  char hexmap[17] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','.'};

  for(i=0;i<BUFLEN;i++)
    buf[i]=0;

  if(argc<2)
  {
    printf("usage: %s <int>\n", argv[0]);
    return 1;
  }
  n = atoi(argv[1]);
  i = 0;
  printf("n: %d\n", n);

  for(i=0; i<4; i++)
  {
    cn = (n>>4*i) & 0xF;
    c  = (cn>15) ? hexmap[16] : hexmap[cn];
    printf("cn: %d, c: %c\n", cn, c);

    buf[3-i] = (cn>15) ? hexmap[16] : hexmap[cn];
  }
  buf[4] = '\0'; // null terminate it

  printf("buf: %s\n", buf);
  return 0;
}
0
jbremnant
unsigned int hex16 = ((unsigned int) input_int) & 0xFFFF;

input_intは、変換する数値です。 hex16input_intの最下位2バイトになります。コンソールに出力する場合は、%xの代わりに%dをフォーマット指定子として使用すると、16進形式で出力されます。

0
yasouser