开发者

Hex character to int in C++

How can I change a hex character, not string, into a numerical value?

While typing this question, I found many answ开发者_StackOverflow中文版ers on how to convert hex strings to values. However, none work for chars. I remember reading somewhere that this works for strings:

std::string mystr = "12345";
unsigned int myval;
std::stringstream(mystr) >> std::hex >> myval;

However, if I do mystr[x] in a loop, this code will not work. I have tried adding a new line with std::string temp = mystr[x] and changing std::stringstream(mystr) to std::stringstream(temp), but that's not working either.

So how should I do this? Currently, I'm searching through a string of the hex chars ("0123456789abcdef".find(mystr[x]);) and using the index for the value. However, since it searches, it's slow, even if it's only searching through 16 characters.

http://ideone.com/dIyD4


int intval = (hexchar >= 'A') ? (hexchar - 'A' + 10) : (hexchar - '0');


The ternary from levis501 can be expanded to:

int v = (c >= 'A') ? (c >= 'a') ? (c - 'a' + 10) : (c - 'A' + 10) : (c - '0');

But if you want error checking it gets a bit messy:

int v = (c < '0')  ? -1 :
        (c <= '9') ? (c - '0') :
        (c < 'A')  ? v = -1 :
        (c <= 'F') ? (c - 'A' + 10) :
        (c < 'a')  ? v = -1 :
        (c <= 'f') ? (c - 'a' + 10) : -1;

It doesn't look much better in if-else blocks:

int v = -1;
if ((c >= '0') && (c <= '9'))
    v = (c - '0');
else if ((c >= 'A') && (c <= 'F'))
    v = (c - 'A' + 10);
else if ((c >= 'a') && (c <= 'f'))
    v = (c - 'a' + 10);

Since I wanted a fast implementation and validation, I went for a lookup table:

int ASCIIHexToInt[] =
{
    // ASCII
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
    -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

    // 0x80-FF (Omit this if you don't need to check for non-ASCII)
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
};

In this case it's just:

int v = ASCIIHexToInt[c];
if (v < 0)
    // Invalid input

Runnable examples are (hopefully) here and here.


You already have a solution that works with strings. Use it for chars too:

#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
  char val = 'A';
  unsigned int myval;
  std::stringstream ss;
  ss << val;
  ss >> std::hex >> myval;
  cout << myval << endl;
}

Code


Something like the following?

//!         \return
//!             The numeric value of ch, if it is hex, otherwise -1
int
fromHexChar( char ch )
{
    static char const hexChars[] = "0123456789ABCDEF";
    char const* p = std::find( begin( hexChars ), end( hexChars ),
                               ::tolower( (unsigned char)ch ) );
    return p == end( hexChars )
        ? -1
        : p - begin( hexChars );
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜