十六进制字符转整数的转换

5

我正在逐个字节地从UART读取数据。这些数据被保存到一个字符中。 在起始字节之后的字节表示接下来的字节数(十六进制)。我需要将这个十六进制数转换成整数,以便统计需要读取的字节数。

目前,我只是将其强制转换为int类型。这是我的代码:

char ch;
int bytes_to_read;
while(1){
    serial_read(UART_RX, &ch, sizeof(char));
    if(/*2nd byte*/){
        bytes_to_read = (int)ch;
    }
}

我读过关于strtol()的内容,但它需要char数组作为输入。应该怎么做才是正确的?


2
你能提供一个例子吗?十六进制数在字节中如何编码? - Joni
3
“as a hexadecimal”是指以十六进制表示的文本形式出现吗?我之所以问是因为这里很多人在说“hex”时实际上指的是“binary”,也就是原始字节数据。 - unwind
你想要转换哪个十六进制数?请明确说明。 - Aadil Ahmad
4
在这种情况下,您的代码已经做了正确的事情,即只需将char强制转换为int——那么实际的问题是什么? - Paul R
1
@user3490458,你是否将0x03解读为4个字符0x03,还是作为一个字节的表示 0x03 和值 3?请确保你清楚价值和表示之间的区别。 - glglgl
显示剩余2条评论
3个回答

16

你的问题不太清楚,但是假设ch是一个十六进制字符代表字节的数量,那么你可以使用一个简单的函数将十六进制转换为整数,例如:

int hex2int(char ch)
{
    if (ch >= '0' && ch <= '9')
        return ch - '0';
    if (ch >= 'A' && ch <= 'F')
        return ch - 'A' + 10;
    if (ch >= 'a' && ch <= 'f')
        return ch - 'a' + 10;
    return -1;
}

然后:

bytes_to_read = hex2int(ch);


请注意,如果ch只是一个原始值(即不是十六进制字符),那么您现有的方法应该是可以正常工作的:

bytes_to_read = (int)ch;

2
为什么不直接使用 atoi() 函数呢? - code monkey
4
两个主要原因:(i)atoi使用字符串而不是单个char;(ii)atoi使用十进制数(基数为10),而不是十六进制数(基数为16)。 - Paul R

3

strtol作用于字符串,ch是一个char类型的变量,因此需要将this字符转换为有效的字符串。

char str[2] = {0};
char chr = 'a';

str[0] = chr;

并使用带有基数为16strtol

long num = strtol(str, NULL, 16);

printf("%ld\n", num);

在处理单个字符时,使用整个字符数组有点过度了。 - user3932000
@user3932000 什么是过度设计?这个2字节数组在堆栈上,没有涉及到动态内存,也没有昂贵的任务需要执行,请重新审视一下你对过度设计的概念。 - David Ranieri
在我看来,这个概念本身就是过度设计——将一个字符转换为长度为1的字符串,调用库函数,然后再将其强制转换为整数...当一个简单的if-then函数就可以解决问题时。 - user3932000

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接