我将十六进制值存储为字符:
char A = '0';
char B = '6';
char C = 'E';
...我需要将它们转换为整数。我知道'atoi',但这仅适用于十进制编码的字符值。有没有类似的功能?
int v = (A > '9')? (A &~ 0x20) - 'A' + 10: (A - '0');
对 ASCII 是正确的。对于其他字符集,类似的方法会起作用,但你会想要toupper
而不是&~ 0x20
.
你可以试试strtol
。但strtol
需要一个 0 终止char *
,所以:
long x = strtol((char[]){A, 0}, NULL, 16);
在 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);
您可以明确声明您想使用 base 16strtol
char C = 'E';
int num = strtol (&C ,NULL,16); // 14
请注意,这C
不是一个以空结尾的数组,如果您可以将字符更改为以下内容,则可以轻松解决:
char C[] = "E";
int num = strtol(C, NULL, 16);
显而易见的解决方案是制作一个字符串,并在其上使用标准转换技术:
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 ) ];
#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;
}
我有一个类似的问题,但我也涉及验证它是一个有效的十六进制字符。下面是我将十六进制字符转换为二进制半字节的解决方案。(注意:您可能需要将 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 |