c - 如何为 strtol 设置限制

Posted

技术标签:

【中文标题】c - 如何为 strtol 设置限制【英文标题】:c - How to set limits for strtol 【发布时间】:2017-03-02 09:41:51 【问题描述】:

我正在尝试 strtol 将包含 ASCII HEX 值的 uint8_t 数组的一部分转换为整数值。这意味着串行端口上接收到的字节被格式化为“89ABC”等ASCII值。

但是strtol 从起始位置转换接收到的uint8_t 数组的其余部分,给我一个完全错误的值。所以我必须这样做:

tempvalue = MerdPC.buf[15]; MerdPC.tiltcmd=(uint8_t)strtol(&tempvalue, NULL, 16);
tempvalue = MerdPC.buf[16]; MerdPC.tiltparam=((uint16_t)strtol(&tempvalue, NULL, 16))<<8;
tempvalue = MerdPC.buf[17]; MerdPC.tiltparam|=((uint16_t)strtol(&tempvalue, NULL, 16))<<4;
tempvalue = MerdPC.buf[18]; MerdPC.tiltparam|=(uint16_t)strtol(&tempvalue, NULL, 16);

这很有效。但是有没有更好的方法,不涉及临时变量?

编辑:

输入字符串示例为:

十六进制值:23 31 43 30 30 30 30 30 30 30 30 30 30 30 30 31 37 38 39 0D 0A

ASCII:#1C0000000000001789..

四个粗体字符分别是tiltcmd字节和tiltparam字节。

【问题讨论】:

strtol 无法做到这一点。你的方法,即使它有效,也不是最优雅的。那些神奇的数字 15、16、17、18 是什么?您可以一次将 4 个字节提取到一个字符串中,然后在该字符串上调用 strtol 请注意,某些编译器不会将uint8_t 视为字符类型。请改用char 这些数字是接收到的字节数组中的元素编号。 15 是一个四位命令 ID,表示从 '0' 到 'F' 的 ASCII HEX,16-18 是构成 12 位命令参数的字节,表示从 '000' 到 'FFF' 的 ASCII HEX。 我不知道tempvalue 是什么。你应该从产生一个有意义的例子开始。 因为你的十六进制数是最后一行,你可以result = strtoul(buffer+15,NULL,16); 【参考方案1】:

这有帮助吗?

char tiltparam[] = "#1C0000000000001789..";

char temp[5] =  0 ;
strncpy(temp, &tiltparam[15], 4);
int tempvalue = strtol(temp, NULL, 10);
...

我们仍然需要temp 缓冲区,但它比您的解决方案更短且更具可读性。

或者如果你在其他地方有更多这样的转化,你可以做一个函数:

int ExtractHex(const char *hexstr, int offset)

    char temp[5] =  0 ;
    strncpy(temp, &hexstr[offset], 4);
    return strtol(temp, NULL, 10);

...
int somevalue = ExtractHex(tiltparam, 15);
...

【讨论】:

谢谢。我看到没有办法使用临时变量/缓冲区。但是您使用strncpy 的方法比我的要好。 :-) 略有改进的版本:char temp[5]; memcpy(temp, &amp;hexstr[offset], 4); temp[4] = '\0';。做同样的工作,但执行速度更快。

以上是关于c - 如何为 strtol 设置限制的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Kubernetes 作业设置时间限制?

NS2:如何为节点设置队列限制

如何为从库中选择的视频设置持续时间限制

如何为 Apple 的大图像缩小 iOS 示例设置最大缩放限制?

如何为css中的文本设置特定的像素或字符宽度限制

如何为不同的屏幕设置自动大小文本