Arduino十六进制到十进制转换

时间:2017-07-30 04:02:21

标签: c++ arduino hex decimal

我需要将十六进制字符串转换为十进制值。我使用了以下方法。但有时它会返回错误的十进制值。

十六进制字符串的格式为“00 00 0C 6E”

unsigned long hexToDec(String hexString) {
  unsigned long decValue = 0;
  int nextInt;
  for (long i = 0; i < hexString.length(); i++) {
    nextInt = long(hexString.charAt(i));
    if (nextInt >= 48 && nextInt <= 57) nextInt = map(nextInt, 48, 57, 0, 9);
    if (nextInt >= 65 && nextInt <= 70) nextInt = map(nextInt, 65, 70, 10, 15);
    if (nextInt >= 97 && nextInt <= 102) nextInt = map(nextInt, 97, 102, 10, 15);
    nextInt = constrain(nextInt, 0, 15);
    decValue = (decValue * 16) + nextInt;
  }
  return decValue;
}

3 个答案:

答案 0 :(得分:3)

空白正在污染转换。试试这个:

#include <iostream>
#include <string>
#include <cctype>
using namespace std;

unsigned long hexToDec(string hexString) {
  unsigned long decValue = 0;
  char nextInt;
  for ( long i = 0; i < hexString.length(); i++ ) {
    nextInt = toupper(hexString[i]);
    if( isxdigit(nextInt) ) {
        if (nextInt >= '0' && nextInt <= '9') nextInt = nextInt - '0';
        if (nextInt >= 'A' && nextInt <= 'F') nextInt = nextInt - 'A' + 10;
        decValue = (decValue << 4) + nextInt;
    }
  }
  return decValue;
}

int main() {
    string test = "00 00 00 0c 1e";
    printf("'%s' in dec = %ld\n", test.c_str(), hexToDec(test));
    return 0;
}

output:
'00 00 00 0c 1e' in dec = 3102

答案 1 :(得分:1)

您的十六进制字符串包含空格,但您的代码不会跳过它们,而constrain()函数会有效地将空格转换为0xF,最终会导致错误的结果。除此之外你的代码还可以。

如果我在以下情况之后建议进行最少量的更改:

nextInt = long(hexString.charAt(i));

将其添加到代码中:

if(isspace(nextInt))
   continue;

请注意isspace()函数是C标准库函数,它是ctype.h头文件中的原型。

但是如果我要对整个代码发表评论,你就会调用太多函数来完成一项可以在没有任何函数调用的情况下完成的工作。

答案 2 :(得分:0)

  1. 为什么要硬编码ASCII值?只需使用char文字 - '0''9''a''f',...;它们更具可读性。
  2. 没有必要对所有map进行简单的数学运算;此外,没有必要constrain,它只是隐藏你的问题(见下一点)。
  3. 如果您遇到的角色不在[0-9a-fA-F]范围而不是跳过它,那么您只是将其ASCII值限制为0-15,这绝对不是您想要做的。
  4. 所以:

    unsigned long hexToDec(String hexString) {
        unsigned long ret;
        for(int i=0, n=hexString.length(); i!=n; ++i) {
            char ch = hexString[i];
            int val = 0;
            if('0'<=ch && ch<='9')      val = ch - '0';
            else if('a'<=ch && ch<='f') val = ch - 'a' + 10;
            else if('A'<=ch && ch<='F') val = ch - 'A' + 10;
            else continue; // skip non-hex characters
            ret = ret*16 + val;
        }
        return ret;
    }
    

    请注意,如果您获得的数据是某个整数的 big-endian 转储,这将提供正确的结果。