将Hex Char转换为Int - 有更好的方法吗?

时间:2009-12-30 18:09:21

标签: c++ parsing hex

我编写了一个函数,用于从Sirit IDentity MaX AVI阅读器中获取数据,并解析出设施代码和密钥卡号。我目前如何做到这一点,但有更好的方法吗?似乎有点hackish ...... buff& buf的大小是264

bufbuff是char

从读者收到的数据:

  

2009/12/30 14:56:18 epc0 LN:001   C80507A0008A19FA 0000232F Xlat'd

char TAccessReader::HexCharToInt(char n)
{
    if (n >= '0' && n <= '9')
        return (n-'0');
    else

    if (n >= 'A' && n <= 'F')
        return (n-'A'+10);
    else
        return 0;
}

bool TAccessReader::CheckSirit(char *buf, long *key_num, unsigned char *fac) {

   unsigned short i, j, k;

   *key_num = 0; // Default is zero
   memset(buff, 0, sizeof(buff));

   i = sscanf(buf, "%s %s %s %s %s %s %s", &buff[0], &buff[20], &buff[40],
              &buff[60], &buff[80], &buff[140], &buff[160]);
   if (i == 7 && buff[147] && !buff[148]) {
       // UUGGNNNN UU=spare, GG=Facility Code, NNNN=Keycard Number (all HEX)

       // get facility code

       *fac = HexCharToInt(buff[142]) * 16 + HexCharToInt(buff[143]);
       *key_num = (unsigned short)HexCharToInt(buff[144]) * 4096 +
                  (unsigned short)HexCharToInt(buff[145]) * 256 +
                  (unsigned short)HexCharToInt(buff[146]) * 16 +
                  HexCharToInt(buff[147]);
   }
   // do some basic checks.. return true or false
}

3 个答案:

答案 0 :(得分:8)

只需使用std::stringstream

#include <sstream>
#include <iostream>

using namespace std;

int main() {
    unsigned int x;   
    stringstream ss;
    ss << hex << "ff";
    ss >> x;
    // output it as a signed type
    cout << static_cast<int>(x) << endl;
}

您也可以直接使用来自C:

strtol
#include <cstdlib>
#include <iostream>

using namespace std;

int main() {
    string s = "ff";
    char *p;
    long n = strtol(s.c_str(), &p, 16);
    if (*p != 0) {
        cout << "fail" << endl;
    }
    else {
        cout << n << endl;
    }
}

答案 1 :(得分:1)

由于您已经在使用sscanf,为什么不为它解析十六进制数字:

sscanf(buff, "%x %x", &val1, &val2);

答案 2 :(得分:1)

这是获取所需数据的简便方法。我在访问控制业务方面工作,所以这对我很感兴趣......

template<typename TRet, typename Iterator>
TRet ConvertHex(Iterator begin) {
    unsigned long result;

    Iterator end = begin + (sizeof(TRet) * 2);
    std::stringstream ss(std::string(begin, end));
    ss >> std::hex >> result;

    return result;
}

bool TAccessReader::CheckSirit(char *buf, long *key_num, unsigned char *fac) {
   *key_num = 0; // Default is zero

   std::istringstream sbuf(std::string(buf, buf+264));

   // Stuff all of the string elements into a vector
   std::vector<std::string> elements;
   std::copy (std::istream_iterator<std::string>(sbuf), std::istream_iterator<std::string>(), std::back_inserter (elements));

   // We're interested in the 6th element
   std::string read = elements[5];

   if (read.length() == 8) {
       // UUGGNNNN UU=spare, GG=Facility Code, NNNN=Keycard Number (all HEX)

       // get facility and card code
       std::string::const_iterator iter = read.begin();
       *fac = ConvertHex<unsigned char>(iter + 2);
       *key_num = ConvertHex<unsigned short>(iter + 4);
   }
   // do some basic checks.. return true or false
}