2010-11-03 69 views
18

Tôi cần chuyển đổi giá trị hex thành 2 byte để lưu trữ trong mảng char, trong C. Làm thế nào tôi có thể thực hiện việc này?Chuyển đổi giá trị hex int thành 2 byte trong C

+0

loại dữ liệu int là 32-bit, trong khi giá trị hex 2 byte là 8 bit. Nếu int của bạn là> 255 nó sẽ không phù hợp với giá trị hex của bạn (nó sẽ tràn). Bạn có nghĩa là ký/unsigned char thay vì int? – invert

+1

@ wez: int không nhất thiết là 32 bit. Nhưng câu hỏi của bạn là một câu hỏi hay, anh ấy cần phải cẩn thận để biết tràn. – Vicky

+0

Câu hỏi này trông giống như một bài tập về nhà ... Điều này có đúng không? Nếu có, hãy thêm thẻ "bài tập về nhà". –

Trả lời

30

Nếu bạn được phép sử dụng chức năng thư viện:

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

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

số nguyên của bạn có thể chứa nhiều hơn bốn chữ số hex giá trị của dữ liệu, do đó kiểm tra đầu tiên.

Nếu bạn không được phép sử dụng chức năng thư viện, chia nó ra thành nybbles bằng tay:

#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'; 
} 
+0

Từ khi nhìn thấy câu trả lời của người khác, có vẻ như họ đang giải thích "giá trị hex hai byte" nghĩa là hai nybbles, mỗi ký tự được biểu diễn bằng một ký tự hex. Tôi lấy nó để có nghĩa là hai byte dữ liệu, mỗi byte đại diện bởi hai ký tự hex. Bạn cần phải làm rõ ý của bạn! – Vicky

+0

Cảm ơn câu trả lời @Vicky. Sử dụng nó để xây dựng các chức năng trong câu trả lời dưới đây. – 10SecTom

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

Có thể bạn sẽ muốn kiểm tra tài liệu sprintf(). Hãy cẩn thận rằng mã này không phải là rất an toàn. Nếu x lớn hơn 0xFFFF, chuỗi cuối cùng sẽ có nhiều hơn 4 ký tự và không vừa. Để làm cho nó an toàn hơn, hãy xem snprintf().

+0

nếu int là 11. Tôi cần kết quả 2 byte là 0 B là 11 trong hex. – MBU

+0

Sai, hai ký tự đó là một nửa byte, còn được gọi là nibbles. Một byte (8-bit, 0-255) bao gồm 2 ký tự hex. Do đó, 2 byte được tạo thành từ 4 ký tự hex. Mỗi char hex (hoặc nibble) có 4 bit (0-15 hoặc 0-F). –

0

Có lẽ thử một cái gì đó như thế này:

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

Mã này giả định các chữ cái từ A đến F chiếm các điểm liên tiếp. Điều này không được đảm bảo bởi ngôn ngữ C. –

+0

Bạn có thể nghĩ đến việc triển khai hoặc mã hóa không có các chữ cái liên tiếp không? –

+3

Mã Baudot, "mã-UPP" của USSR (Код-УПП). – Vovanium

4

Giả sử int là 32 bit;

Cách đơn giản nhất: chỉ cần sử dụng sprintf()

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

Bây giờ sử dụng hexval [0] thru hexval [3]; nếu bạn muốn sử dụng nó như là một chuỗi null-chấm dứt sau đó thêm hexval[4]=0;

+1

Bạn sẽ nhận được kết quả không thể đoán trước (thậm chí bị lỗi) khi 0xFF Vovanium

+0

Không. Kể từ khi sprintf định dạng intval thành một chuỗi. Vì vậy, 0xFFFF (mà không phải là giá trị tối đa cho một số nguyên 32 bit bằng cách này) sẽ là bốn F và những người sẽ không phù hợp với hexval [3], vì bạn cũng phải xem xét trailing 0. Bạn sẽ không phải thêm hexval [2] = 0 bằng cách này. –

+0

okay, chỉ trả tiền nửa tâm trí - bạn đã đúng - sửa nó – slashmais

1

Thay vì sprintf, tôi sẽ khuyên bạn sử dụng snprintf để thay thế.

#include <stdio.h> 

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

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

An toàn hơn rất nhiều và có sẵn trong mọi trình biên dịch.

0

Hầu hết các câu trả lời đều tuyệt vời, chỉ có một điều tôi thêm: bạn có thể sử dụng sizeof để đặt trước số byte đúng cách an toàn. Mỗi byte có thể mất đến hai chữ số hex (255 -> ff), do đó, nó là hai ký tự mỗi byte. Trong ví dụ này, tôi thêm hai ký tự cho tiền tố '0x' và một ký tự cho dấu NUL.

int bar; 
// ... 
char foo[sizeof(bar) * 2 + 3]; 
sprintf(foo, "0x%x", bar); 
0
unsigned int hex16 = ((unsigned int) input_int) & 0xFFFF; 

input_int là số bạn muốn chuyển đổi. hex16 sẽ có ít nhất 2 byte đáng kể là input_int. Nếu bạn muốn in nó vào bảng điều khiển, hãy sử dụng %x làm trình định dạng định dạng thay vì %d và nó sẽ được in ở định dạng hex.

2

Thông thường tôi khuyên bạn nên sử dụng các giải pháp dựa trên sprintf được đề xuất bởi những người khác. Nhưng khi tôi viết một công cụ phải chuyển đổi hàng tỷ mục thành hex, sprintf quá chậm. Đối với ứng dụng đó tôi đã sử dụng một mảng phần tử 256, ánh xạ các byte thành chuỗi.

Đây là giải pháp không hoàn chỉnh để chuyển đổi 1 byte, đừng quên thêm giới hạn kiểm tra và đảm bảo mảng là tĩnh hoặc toàn cầu, tạo lại nó cho mỗi kiểm tra sẽ giết hiệu suất.

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

Đây là cách thô lỗ để thực hiện.Nếu chúng ta không thể tin tưởng việc mã hóa các giá trị ascii được liên tiếp, chúng ta chỉ cần tạo một ánh xạ các giá trị hex trong char. Có lẽ có thể được tối ưu hóa, dọn dẹp và làm đẹp hơn. Ngoài ra giả định chúng tôi chỉ xem xét thu thập 32bits == 4 ký tự hex cuối cùng.

#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

32 bit/4 bit-mỗi-hex-ký tự = 8 ký tự. Không 4. –

2

Đã tìm ra cách nhanh chóng để thử nghiệm và hoạt động.

int value = 11; 

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

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

kết quả là:

000B 

đó là 11 trong hex.

0

Chức năng này hoạt động như một nét duyên dáng.

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

asumming sau:

typedef unsigned char BYTE; 
typedef unsigned short WORD; 

Ví dụ về sử dụng:

chúng ta muốn đạt được điều này:

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

unsigned char _byteHex[2]; 
WORD2WBYTE(_byteHex, 92); 
1
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); 
.... 
+2

Chăm sóc để giải thích câu trả lời của bạn để mọi người có thể học hỏi từ nó? – Machavity

0

bạn có thể sử dụng điều này thật đơn giản và dễ dàng để chuyển đổi

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

    }hex_da; 
    short int dec_val; 
}hex2dec; 

hex2dec value; 
value.dec_val=10; 

Bây giờ giá trị hex được lưu trữ trong cấu trúc hex_da để truy cập thêm.

0

Sử dụng câu trả lời của Vicky trên

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

Đối với chiều dài cố định động của hex

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

Nhưng tiêu cực, bạn phải xử lý nó cho mình.

Các vấn đề liên quan