【问题标题】:C/C++: Converting hexadecimal value in char to integerC/C++:将 char 中的十六进制值转换为整数
【发布时间】:2018-03-28 07:56:23
【问题描述】:

我将十六进制值存储为字符:

char A = '0';
char B = '6';
char C = 'E';

...我需要将它们转换为整数。我知道'atoi',但这仅适用于十进制编码的字符值。有没有类似的功能?

【问题讨论】:

  • 除了atoi你还试过什么?

标签: c++ c char


【解决方案1】:
int v = (A > '9')? (A &~ 0x20) - 'A' + 10: (A - '0');

对 ASCII 是正确的。对于其他字符集,可以使用类似的方法,但您需要 toupper 而不是 &~ 0x20

【讨论】:

  • 我需要新值作为整数,而不是字符。
  • @jurij:char 是整数类型,大到足以容纳 0-15,但我改变了它让你开心。
  • @junj,将char v 替换为int v。你知道char 只是最短的有符号整数类型,对吧?
  • 是的,但是我需要新的值作为 int 以便稍后对它们进行一些数学运算。
  • 这非常依赖于编码。例如,它假设'A'-'F' 和'a'-'f' 的代码比'0'-'9' 的代码大(在数字上)。这对于 ASCII 是正确的,但对于其他编码则不一定。 (例如,EBCDIC 不是这样。)
【解决方案2】:

你可以试试strtol。但是strtol 需要一个以 0 结尾的 char *,所以:

long x = strtol((char[]){A, 0}, NULL, 16);

【讨论】:

  • 但请注意,(char[]){} 需要支持 C++11 初始化语法的最新编译器版本。
  • @BenVoigt 实际上我们从 C99 开始就有了。
【解决方案3】:

您可以明确声明您希望使用基数为 16 的 strtol

char C = 'E';
int num = strtol (&C ,NULL,16); // 14

注意C 不是以空结尾的数组,如果您可以将字符更改为以下内容即可轻松解决:

char C[] = "E";
int num = strtol(C, NULL, 16);

【讨论】:

  • &C 不是以 null 结尾的数组!
  • 如果Cshortintlong 或任何其他大于char 的整数类型,则应该在小端系统上工作:)(指针也应该是然后投射到char *
  • 这是未定义的行为,不仅仅是生活在边缘。它可能在大多数情况下都有效,但有时会给出错误的值。甚至崩溃(尽管我承认我觉得这不太可能)。
  • 当然,但此插图的目标是使用 strtol 及其可选的基本功能。我会做一些修改。
【解决方案4】:

显而易见的解决方案是制作一个单字符的字符串,并使用 标准转换技术:

std::istringstream tmp( std::string( 1, A ) );
tmp >> anInt;

不过,它有点重(轻描淡写),而且可能不是很重 在运行时方面效率很高(如果我听说过的话,那就是 litote)。

一种简单而可靠的解决方案是查表:

static char const digits[] = "0123456789ABCDEF";
int value = std::find(digits, digits + 16, A) - digits;
if (value >= 16) {
    //  A wasn't a hex digit...
}

另一种选择(并且更快)是使用字符作为索引 一张桌子:

static signed char const values[] =
{
    -1, -1, -1, -1, -1, -1, -1, -1,     //  0x00-0x07
    //  ...
     0,  1,  2,  3,  4,  5,  6,  7,     //  0x30-0x37
     8,  9, -1, -1, -1, -1, -1, -1,     //  0x38-0x3F
    -1, 10, 11, 12, 13, 14, 15, -1,     //  0x40-0x47
    //  ...
    -1, 10, 11, 12, 13, 14, 15, -1,     //  0x60-0x67
    //  ...
};


int value = values[static_cast<unsigned char>( A )];

请注意,这非常取决于编码;你可能想要 在运行时从数字列表构建它,以避免任何编码 问题。比如:

struct ValueTable
{
    signed char values[256];
    ValueTable()
    {
        std::fill( begin(values), end(values), -1 );
        static char const digits[] = "0123456789ABCDEF";
        for ( int i = 0; i < 16; ++ i ) {
            values[ digits[i] = i;
            values[ tolower( digits[i] ) ] = i;
        }
    }
};
static ValueTable const map;

//   ...
int value = map.values[ static_cast<unsigned char>( A ) ];

【讨论】:

    【解决方案5】:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int xtoi(char c)
    {
        int v = -1;
        char w=toupper(c);
        if(w >= 'A' && w <= 'F'){
            v = w - 'A' + 0x0A;
        }else if (w >= '0' && w <= '9'){
            v = w - '0';
        }
    
        return v;
    }
    
    int main(int argc,char **argv)
    {
        printf("v:%p\n",argc == 2 ? xtoi(argv[1][0]):-1);
        return 0;
    }
    

    【讨论】:

      【解决方案6】:

      在 C 中:

      const char chrs[] = "0123456789ABCDEF";
      
      int value = -1; // sentinel
      const char *loc = strchr(chrs, ch);
      if (loc)
          value = loc - chrs;
      

      或者,使用 C++:

      const std::string chrs("0123456789ABCDEF");
      int value = chrs.find(ch);
      

      【讨论】:

        【解决方案7】:

        我遇到了类似的问题,但我的问题还涉及验证它是否有效 十六进制字符。下面是我的解决方案,将十六进制字符转换为 二进制半字节。 (注意:您可能需要将 uint8_t 更改为 int)。

        这种方法的好处是无需单独检查每个 针对查找表的字符。最多只有 6 个比较(除了 空指针守卫)才能输出答案。

        /**-----------------------------------------------------------------------------
          @brief Converts Hexidecimal Char Value Into Binary Nibble Format
          Converts 0-9 & a-f & A-F Hex notation to binary nibble between 0x00 to 0x0F
          Return: True if valid nibble is avaliable at nibble_out else it returns false
        ------------------------------------------------------------------------------*/
        bool char_to_nibble(const char ch, uint8_t *nibble_out)
        { /* Assumes char ch is encoded in ascii */
          if (!nibble_out)
          { /* Output Pointer Cannot Be Null */
            return false;
          }
          if ( '0' <= ch && ch <= '9' )
          { /* Integer Character */
            *nibble_out = ch - '0';
            return true;
          }
          if ( 'a' <= ch && ch <= 'f' )
          { /* Lowercase Letter Character */
            *nibble_out = ch - 'a' + 10;
            return true;
          }
          if ( 'A' <= ch && ch <= 'F' )
          { /* Upper Case Character */
            *nibble_out = ch - 'A' + 10;
            return true;
          }
          return false;
        }
        

        确认以上功能正常。下面的测试程序中的证明。

        测试程序

        这个程序演示了 char_to_nibble() 及其用法。

        /*******************************************************************************
          Parse Hexidecimal Char to binary Nibble ( In C Language )
          Brian Khuu 2017
        *******************************************************************************/
        // Tip: tcc -run ${This File}
        #include <stdint.h>  // Standard Integer (e.g. uint8_t )
        #include <stdbool.h> // Standard Boolean
        #include <stdio.h>   // printf()
        #include <ctype.h>   // isprint()
        #include <stdio.h>   // sscanf()
        
        /**-----------------------------------------------------------------------------
          @brief Converts Hexidecimal Char Value Into Binary Nibble Format
          Converts 0-9 & a-f & A-F Hex notation to binary nibble between 0x00 to 0x0F
          Return: True if valid nibble is avaliable at nibble_out else it returns false
        ------------------------------------------------------------------------------*/
        bool char_to_nibble(const char ch, uint8_t *nibble_out)
        { /* Assumes char ch is encoded in ascii */
          if (!nibble_out)
          { /* Output Pointer Cannot Be Null */
            return false;
          }
          if ( '0' <= ch && ch <= '9' )
          { /* Integer Character */
            *nibble_out = ch - '0';
            return true;
          }
          if ( 'a' <= ch && ch <= 'f' )
          { /* Lowercase Letter Character */
            *nibble_out = ch - 'a' + 10;
            return true;
          }
          if ( 'A' <= ch && ch <= 'F' )
          { /* Upper Case Character */
            *nibble_out = ch - 'A' + 10;
            return true;
          }
          return false;
        }
        
        /*******************************************************************************
          Demonstration of char_to_nibble()
        *******************************************************************************
          - Running this program without an argument will spit out the full table.
          - Running this program with one char per argument will run a partial test.
        */
        
        void test(const char ch)
        { /* Runs a test on this char and display the result */
          uint8_t nibble = 0;
          /* Function Under Test */
          bool result = char_to_nibble(ch, &nibble);
          /* Print Result */
          printf("| 0x%02X, `%c` | %2u     | %s |\r\n", (uint8_t) ch, (isprint(ch)?ch:' '), nibble, (result?"**TRUE**":" FALSE  ") );
        }
        
        #define ARGTOINT(arg, var) if((argc-1) >= arg){sscanf(argv[arg], "%d", &var);}
        
        int main(int argc, char *argv[])
        {
          printf("| Input     | Output | Is Hex?  |\r\n");
          printf("|-----------|--------|----------|\r\n");
          if (argc == 1)
          { /* self test on no param */
            for (uint16_t i = 0 ; i < 256 ; i++) test((char)i);
            return 0;
          }
          for (int i = 1 ; i < argc ; i++)
          { /* Process user input (e.g. "a b c d e ..." )*/
            char ch = *(argv[i]);
            test(ch);
          }
          return 0;
        }
        

        全表输出

        此表是通过运行上述测试程序(空 arg 模式)生成的。 这表明该函数按预期工作。

        | Input     | Output | Is Hex?  |
        |-----------|--------|----------|
        | 0x00, ` ` |  0     |  FALSE   |
        | 0x01, ` ` |  0     |  FALSE   |
        | 0x02, ` ` |  0     |  FALSE   |
        | 0x03, ` ` |  0     |  FALSE   |
        | 0x04, ` ` |  0     |  FALSE   |
        | 0x05, ` ` |  0     |  FALSE   |
        | 0x06, ` ` |  0     |  FALSE   |
        | 0x07, ` ` |  0     |  FALSE   |
        | 0x08, ` ` |  0     |  FALSE   |
        | 0x09, ` ` |  0     |  FALSE   |
        | 0x0A, ` ` |  0     |  FALSE   |
        | 0x0B, ` ` |  0     |  FALSE   |
        | 0x0C, ` ` |  0     |  FALSE   |
        | 0x0D, ` ` |  0     |  FALSE   |
        | 0x0E, ` ` |  0     |  FALSE   |
        | 0x0F, ` ` |  0     |  FALSE   |
        | 0x10, ` ` |  0     |  FALSE   |
        | 0x11, ` ` |  0     |  FALSE   |
        | 0x12, ` ` |  0     |  FALSE   |
        | 0x13, ` ` |  0     |  FALSE   |
        | 0x14, ` ` |  0     |  FALSE   |
        | 0x15, ` ` |  0     |  FALSE   |
        | 0x16, ` ` |  0     |  FALSE   |
        | 0x17, ` ` |  0     |  FALSE   |
        | 0x18, ` ` |  0     |  FALSE   |
        | 0x19, ` ` |  0     |  FALSE   |
        | 0x1A, ` ` |  0     |  FALSE   |
        | 0x1B, ` ` |  0     |  FALSE   |
        | 0x1C, ` ` |  0     |  FALSE   |
        | 0x1D, ` ` |  0     |  FALSE   |
        | 0x1E, ` ` |  0     |  FALSE   |
        | 0x1F, ` ` |  0     |  FALSE   |
        | 0x20, ` ` |  0     |  FALSE   |
        | 0x21, `!` |  0     |  FALSE   |
        | 0x22, `"` |  0     |  FALSE   |
        | 0x23, `#` |  0     |  FALSE   |
        | 0x24, `$` |  0     |  FALSE   |
        | 0x25, `%` |  0     |  FALSE   |
        | 0x26, `&` |  0     |  FALSE   |
        | 0x27, `'` |  0     |  FALSE   |
        | 0x28, `(` |  0     |  FALSE   |
        | 0x29, `)` |  0     |  FALSE   |
        | 0x2A, `*` |  0     |  FALSE   |
        | 0x2B, `+` |  0     |  FALSE   |
        | 0x2C, `,` |  0     |  FALSE   |
        | 0x2D, `-` |  0     |  FALSE   |
        | 0x2E, `.` |  0     |  FALSE   |
        | 0x2F, `/` |  0     |  FALSE   |
        | 0x30, `0` |  0     | **TRUE** |
        | 0x31, `1` |  1     | **TRUE** |
        | 0x32, `2` |  2     | **TRUE** |
        | 0x33, `3` |  3     | **TRUE** |
        | 0x34, `4` |  4     | **TRUE** |
        | 0x35, `5` |  5     | **TRUE** |
        | 0x36, `6` |  6     | **TRUE** |
        | 0x37, `7` |  7     | **TRUE** |
        | 0x38, `8` |  8     | **TRUE** |
        | 0x39, `9` |  9     | **TRUE** |
        | 0x3A, `:` |  0     |  FALSE   |
        | 0x3B, `;` |  0     |  FALSE   |
        | 0x3C, `<` |  0     |  FALSE   |
        | 0x3D, `=` |  0     |  FALSE   |
        | 0x3E, `>` |  0     |  FALSE   |
        | 0x3F, `?` |  0     |  FALSE   |
        | 0x40, `@` |  0     |  FALSE   |
        | 0x41, `A` | 10     | **TRUE** |
        | 0x42, `B` | 11     | **TRUE** |
        | 0x43, `C` | 12     | **TRUE** |
        | 0x44, `D` | 13     | **TRUE** |
        | 0x45, `E` | 14     | **TRUE** |
        | 0x46, `F` | 15     | **TRUE** |
        | 0x47, `G` |  0     |  FALSE   |
        | 0x48, `H` |  0     |  FALSE   |
        | 0x49, `I` |  0     |  FALSE   |
        | 0x4A, `J` |  0     |  FALSE   |
        | 0x4B, `K` |  0     |  FALSE   |
        | 0x4C, `L` |  0     |  FALSE   |
        | 0x4D, `M` |  0     |  FALSE   |
        | 0x4E, `N` |  0     |  FALSE   |
        | 0x4F, `O` |  0     |  FALSE   |
        | 0x50, `P` |  0     |  FALSE   |
        | 0x51, `Q` |  0     |  FALSE   |
        | 0x52, `R` |  0     |  FALSE   |
        | 0x53, `S` |  0     |  FALSE   |
        | 0x54, `T` |  0     |  FALSE   |
        | 0x55, `U` |  0     |  FALSE   |
        | 0x56, `V` |  0     |  FALSE   |
        | 0x57, `W` |  0     |  FALSE   |
        | 0x58, `X` |  0     |  FALSE   |
        | 0x59, `Y` |  0     |  FALSE   |
        | 0x5A, `Z` |  0     |  FALSE   |
        | 0x5B, `[` |  0     |  FALSE   |
        | 0x5C, `\` |  0     |  FALSE   |
        | 0x5D, `]` |  0     |  FALSE   |
        | 0x5E, `^` |  0     |  FALSE   |
        | 0x5F, `_` |  0     |  FALSE   |
        | 0x60, ``` |  0     |  FALSE   |
        | 0x61, `a` | 10     | **TRUE** |
        | 0x62, `b` | 11     | **TRUE** |
        | 0x63, `c` | 12     | **TRUE** |
        | 0x64, `d` | 13     | **TRUE** |
        | 0x65, `e` | 14     | **TRUE** |
        | 0x66, `f` | 15     | **TRUE** |
        | 0x67, `g` |  0     |  FALSE   |
        | 0x68, `h` |  0     |  FALSE   |
        | 0x69, `i` |  0     |  FALSE   |
        | 0x6A, `j` |  0     |  FALSE   |
        | 0x6B, `k` |  0     |  FALSE   |
        | 0x6C, `l` |  0     |  FALSE   |
        | 0x6D, `m` |  0     |  FALSE   |
        | 0x6E, `n` |  0     |  FALSE   |
        | 0x6F, `o` |  0     |  FALSE   |
        | 0x70, `p` |  0     |  FALSE   |
        | 0x71, `q` |  0     |  FALSE   |
        | 0x72, `r` |  0     |  FALSE   |
        | 0x73, `s` |  0     |  FALSE   |
        | 0x74, `t` |  0     |  FALSE   |
        | 0x75, `u` |  0     |  FALSE   |
        | 0x76, `v` |  0     |  FALSE   |
        | 0x77, `w` |  0     |  FALSE   |
        | 0x78, `x` |  0     |  FALSE   |
        | 0x79, `y` |  0     |  FALSE   |
        | 0x7A, `z` |  0     |  FALSE   |
        | 0x7B, `{` |  0     |  FALSE   |
        | 0x7C, `|` |  0     |  FALSE   |
        | 0x7D, `}` |  0     |  FALSE   |
        | 0x7E, `~` |  0     |  FALSE   |
        | 0x7F, ` ` |  0     |  FALSE   |
        | 0x80, ` ` |  0     |  FALSE   |
        | 0x81, ` ` |  0     |  FALSE   |
        | 0x82, ` ` |  0     |  FALSE   |
        | 0x83, ` ` |  0     |  FALSE   |
        | 0x84, ` ` |  0     |  FALSE   |
        | 0x85, ` ` |  0     |  FALSE   |
        | 0x86, ` ` |  0     |  FALSE   |
        | 0x87, ` ` |  0     |  FALSE   |
        | 0x88, ` ` |  0     |  FALSE   |
        | 0x89, ` ` |  0     |  FALSE   |
        | 0x8A, ` ` |  0     |  FALSE   |
        | 0x8B, ` ` |  0     |  FALSE   |
        | 0x8C, ` ` |  0     |  FALSE   |
        | 0x8D, ` ` |  0     |  FALSE   |
        | 0x8E, ` ` |  0     |  FALSE   |
        | 0x8F, ` ` |  0     |  FALSE   |
        | 0x90, ` ` |  0     |  FALSE   |
        | 0x91, ` ` |  0     |  FALSE   |
        | 0x92, ` ` |  0     |  FALSE   |
        | 0x93, ` ` |  0     |  FALSE   |
        | 0x94, ` ` |  0     |  FALSE   |
        | 0x95, ` ` |  0     |  FALSE   |
        | 0x96, ` ` |  0     |  FALSE   |
        | 0x97, ` ` |  0     |  FALSE   |
        | 0x98, ` ` |  0     |  FALSE   |
        | 0x99, ` ` |  0     |  FALSE   |
        | 0x9A, ` ` |  0     |  FALSE   |
        | 0x9B, ` ` |  0     |  FALSE   |
        | 0x9C, ` ` |  0     |  FALSE   |
        | 0x9D, ` ` |  0     |  FALSE   |
        | 0x9E, ` ` |  0     |  FALSE   |
        | 0x9F, ` ` |  0     |  FALSE   |
        | 0xA0, ` ` |  0     |  FALSE   |
        | 0xA1, ` ` |  0     |  FALSE   |
        | 0xA2, ` ` |  0     |  FALSE   |
        | 0xA3, ` ` |  0     |  FALSE   |
        | 0xA4, ` ` |  0     |  FALSE   |
        | 0xA5, ` ` |  0     |  FALSE   |
        | 0xA6, ` ` |  0     |  FALSE   |
        | 0xA7, ` ` |  0     |  FALSE   |
        | 0xA8, ` ` |  0     |  FALSE   |
        | 0xA9, ` ` |  0     |  FALSE   |
        | 0xAA, ` ` |  0     |  FALSE   |
        | 0xAB, ` ` |  0     |  FALSE   |
        | 0xAC, ` ` |  0     |  FALSE   |
        | 0xAD, ` ` |  0     |  FALSE   |
        | 0xAE, ` ` |  0     |  FALSE   |
        | 0xAF, ` ` |  0     |  FALSE   |
        | 0xB0, ` ` |  0     |  FALSE   |
        | 0xB1, ` ` |  0     |  FALSE   |
        | 0xB2, ` ` |  0     |  FALSE   |
        | 0xB3, ` ` |  0     |  FALSE   |
        | 0xB4, ` ` |  0     |  FALSE   |
        | 0xB5, ` ` |  0     |  FALSE   |
        | 0xB6, ` ` |  0     |  FALSE   |
        | 0xB7, ` ` |  0     |  FALSE   |
        | 0xB8, ` ` |  0     |  FALSE   |
        | 0xB9, ` ` |  0     |  FALSE   |
        | 0xBA, ` ` |  0     |  FALSE   |
        | 0xBB, ` ` |  0     |  FALSE   |
        | 0xBC, ` ` |  0     |  FALSE   |
        | 0xBD, ` ` |  0     |  FALSE   |
        | 0xBE, ` ` |  0     |  FALSE   |
        | 0xBF, ` ` |  0     |  FALSE   |
        | 0xC0, ` ` |  0     |  FALSE   |
        | 0xC1, ` ` |  0     |  FALSE   |
        | 0xC2, ` ` |  0     |  FALSE   |
        | 0xC3, ` ` |  0     |  FALSE   |
        | 0xC4, ` ` |  0     |  FALSE   |
        | 0xC5, ` ` |  0     |  FALSE   |
        | 0xC6, ` ` |  0     |  FALSE   |
        | 0xC7, ` ` |  0     |  FALSE   |
        | 0xC8, ` ` |  0     |  FALSE   |
        | 0xC9, ` ` |  0     |  FALSE   |
        | 0xCA, ` ` |  0     |  FALSE   |
        | 0xCB, ` ` |  0     |  FALSE   |
        | 0xCC, ` ` |  0     |  FALSE   |
        | 0xCD, ` ` |  0     |  FALSE   |
        | 0xCE, ` ` |  0     |  FALSE   |
        | 0xCF, ` ` |  0     |  FALSE   |
        | 0xD0, ` ` |  0     |  FALSE   |
        | 0xD1, ` ` |  0     |  FALSE   |
        | 0xD2, ` ` |  0     |  FALSE   |
        | 0xD3, ` ` |  0     |  FALSE   |
        | 0xD4, ` ` |  0     |  FALSE   |
        | 0xD5, ` ` |  0     |  FALSE   |
        | 0xD6, ` ` |  0     |  FALSE   |
        | 0xD7, ` ` |  0     |  FALSE   |
        | 0xD8, ` ` |  0     |  FALSE   |
        | 0xD9, ` ` |  0     |  FALSE   |
        | 0xDA, ` ` |  0     |  FALSE   |
        | 0xDB, ` ` |  0     |  FALSE   |
        | 0xDC, ` ` |  0     |  FALSE   |
        | 0xDD, ` ` |  0     |  FALSE   |
        | 0xDE, ` ` |  0     |  FALSE   |
        | 0xDF, ` ` |  0     |  FALSE   |
        | 0xE0, ` ` |  0     |  FALSE   |
        | 0xE1, ` ` |  0     |  FALSE   |
        | 0xE2, ` ` |  0     |  FALSE   |
        | 0xE3, ` ` |  0     |  FALSE   |
        | 0xE4, ` ` |  0     |  FALSE   |
        | 0xE5, ` ` |  0     |  FALSE   |
        | 0xE6, ` ` |  0     |  FALSE   |
        | 0xE7, ` ` |  0     |  FALSE   |
        | 0xE8, ` ` |  0     |  FALSE   |
        | 0xE9, ` ` |  0     |  FALSE   |
        | 0xEA, ` ` |  0     |  FALSE   |
        | 0xEB, ` ` |  0     |  FALSE   |
        | 0xEC, ` ` |  0     |  FALSE   |
        | 0xED, ` ` |  0     |  FALSE   |
        | 0xEE, ` ` |  0     |  FALSE   |
        | 0xEF, ` ` |  0     |  FALSE   |
        | 0xF0, ` ` |  0     |  FALSE   |
        | 0xF1, ` ` |  0     |  FALSE   |
        | 0xF2, ` ` |  0     |  FALSE   |
        | 0xF3, ` ` |  0     |  FALSE   |
        | 0xF4, ` ` |  0     |  FALSE   |
        | 0xF5, ` ` |  0     |  FALSE   |
        | 0xF6, ` ` |  0     |  FALSE   |
        | 0xF7, ` ` |  0     |  FALSE   |
        | 0xF8, ` ` |  0     |  FALSE   |
        | 0xF9, ` ` |  0     |  FALSE   |
        | 0xFA, ` ` |  0     |  FALSE   |
        | 0xFB, ` ` |  0     |  FALSE   |
        | 0xFC, ` ` |  0     |  FALSE   |
        | 0xFD, ` ` |  0     |  FALSE   |
        | 0xFE, ` ` |  0     |  FALSE   |
        | 0xFF, ` ` |  0     |  FALSE   |
        

        【讨论】:

          猜你喜欢
          • 2011-05-25
          • 1970-01-01
          • 2011-08-11
          • 2013-05-07
          • 2011-08-12
          • 2018-11-28
          • 2018-11-07
          • 2011-08-04
          相关资源
          最近更新 更多