User
User

Reputation: 637

How to form an ASCII(Hex) number using 2 Chars?

I have char byte[0] = '1' (H'0x31)and byte[1] = 'C'(H'0x43)

I am using one more buffer to more buff char hex_buff[0] .i want to have hex content in this hex_buff[0] = 0x1C (i.e combination of byte[0] and byte[1])

I was using below code but i realized that my code is valid for the hex values 0-9 only

char s_nibble1 = (byte[0]<< 4)& 0xf0;

char s_nibble2 =  byte[1]& 0x0f;

hex_buff[0] = s_nibble1 | s_nibble2;// here i want to have 0x1C instead of 0x13

Upvotes: 1

Views: 2232

Answers (4)

alk
alk

Reputation: 70921

What keeps you from using strtol()?

char bytes[] = "1C";
char buff[1];
buff[0] = strtol(bytes, NULL, 16);  /* Sets buff[0] to 0x1c aka 28. */

To add this as per chux's comment: strtol() only operates on 0-terminated character arrays. Which does not necessarily needs to be the case for the OP's question.

Upvotes: 2

Logicrat
Logicrat

Reputation: 4468

It looks like you are trying to convert ASCII hex into internal representation.

There are many ways to do this, but the one I use most often for each nibble is:

int nibval(unsigned short x)
{
    if  (('0' <= x) && ('9' >= x))
    {
        return  x - '0';
    }
    if  (('a' <= x) && ('f' >= x))
    {
        return  x - ('a' - 10);
    }
    if  (('A' <= x) && ('F' >= x))
    {
        return  x - ('A' - 10);
    }

    //  Invalid input
    return  -1;
}

This uses an unsigned int parameter so that it will work for single byte characters as well as wchar_t characters.

Upvotes: 1

Claudi
Claudi

Reputation: 5416

A possible way to do it, without dependencies with other character manipulation functions:

char hex2byte(char *hs)
{
    char b = 0;
    char nibbles[2];
    int i;

    for (i = 0; i < 2; i++) {
        if ((hs[i] >= '0') && (hs[i] <= '9')) 
            nibbles[i] = hs[i]-'0';
        else if ((hs[i] >= 'A') && (hs[i] <= 'F')) 
            nibbles[i] = (hs[i]-'A')+10;
        else if ((hs[i] >= 'a') && (hs[i] <= 'f')) 
            nibbles[i] = (hs[i]-'a')+10;
        else 
            return 0;
    }

    b = (nibbles[0] << 4) | nibbles[1];
    return b;
}

For example: hex2byte("a1") returns the byte 0xa1.

In your case, you should call the function as: hex_buff[0] = hex2byte(byte).

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726539

You are trying to get the nibble by masking out the bits of character code, rather than subtracting the actual value. This is not going to work, because the range is disconnected: there is a gap between [0..9] and [A-F] in the encoding, so masking is going to fail.

You can fix this by adding a small helper function, and using it twice in your code:

int hexDigit(char c) {
    c = toupper(c); // Allow mixed-case letters
    switch(c) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9': return c-'0';
        case 'A':
        case 'B':
        case 'C':
        case 'D':
        case 'E':
        case 'F': return c-'A'+10;
        default: // Report an error
    }
    return -1;
}

Now you can code your conversion like this:

int val = (hexDigit(byte[0]) << 4) | hexDigit(byte[1]);

Upvotes: 2

Related Questions