如何将 stringstream 十六进制字符串字符对转换为单个 uint8_t 等效二进制值

Posted

技术标签:

【中文标题】如何将 stringstream 十六进制字符串字符对转换为单个 uint8_t 等效二进制值【英文标题】:how to convert an ostringstream hex string character pairs to a single unit8_t equivalent binary value 【发布时间】:2020-10-31 08:49:18 【问题描述】:

我正在尝试执行以下操作:

我有一个组装好的 ostringstream 对象,其中包含要传输的十六进制有效负载。说,可能是

03125412349876543210af     (this is representing the data using hex convention in my string)

这个字符串代表 11 个字节,所以例如要传输的最后一个字节是 0xaf(两个字符给我 8 位实际数据)。

我希望读取每对字符,例如字符串中的 '03' 对字符并将其转换为 uint8_t 元素,我将把它推送到 uint8_t 元素的向量上。本质上,我将根据字符串的内容创建一个新的 uint8_t 元素向量,然后传输该向量。

我下面的测试程序对于“int”可以正常工作,但没有给我想要的 uint8_t。是否有一种优雅和/或直接的方式来做我想做的任何人都可以建议的事情?

(注意:示例 3 是为了看看如果使用非十六进制合法值会发生什么。在示例 1 中,像 34r0 这样的值会将 34(hex) 转换为等效的 int 并忽略 r 及其后面的所有内容)。

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

int main()

    cout << "Hello world!" << endl;

    // example 1: making a hex string an int - works
    std::stringstream str1;
    std::string s1 = "5f";
    str1 << s1;
    int value1;
    str1 >> std::hex >> value1;
    cout << value1 << endl; // produces 95 - perfect

    cout << "~~~~~~~~~" << endl;

    // example 2: making a hex string a uint8 - not the result I want
    std::stringstream str2;
    std::string s2 = "5f";
    str2 << s2;
    uint8_t value2;
    str2 >> std::hex >> value2;
    cout << value2 << endl; // produces 5 - not what I want!

    cout << "~~~~~~~~~~~" << endl;

    // example 3: using non-hex values
    std::stringstream str3;
    std::string s3 = "wx";
    str3 << s3;
    uint8_t value3;
    str3 >> std::hex >> value3;
    cout << value3 << endl; // produces w - not what I want!

    // this does not work either
    uint8_t value4;
    cout << "~~~~~~~~~~~~~~" << endl;
    value4 = (uint8_t)value1;
    cout << value4 << endl; // produces - - not what I want!

    cout << "............." << endl;


    return 0;

这个测试程序的输出如下所示:

Hello world!
95
~~~~~~~~~
5
~~~~~~~~~~~
w
~~~~~~~~~~~~~~
_
.............

Process returned 0 (0x0)   execution time : 0.022 s
Press any key to continue.

示例 1 工作正常,但使用 int - 这不是我需要的。

【问题讨论】:

【参考方案1】:

在示例 2 中,您将提取一个 uint8_t,8 位,因此从字符串 5 中提取一个 char

在示例 3 中也是一样,你提取第一个字符,所以 w

对于最后一个示例,它打印一个 char(8 位),95 是 ASCII - 字符。如果要显示数字,cast 将值改为int

value4 = (uint8_t)value1;
cout << (int)value4 << endl;

【讨论】:

嗨曼努埃尔,是的,谢谢你在流媒体产生 95(正确的值)之前正确地将 value4 转换为。所以我可以分两步完成(分配然后强制转换)。尽管如此,我还是忍不住想应该有一种更优雅的方式将十六进制字符串转换为位。 嗨 Manuel,是的,谢谢您在流式传输产生 95(正确值)之前将 value4 正确转换为 int。所以我可以分两步完成(分配然后强制转换)。尽管如此,我还是忍不住想应该有一种更优雅的方式将十六进制字符串转换为位。 @Spangas 我赞成这个问题,因为事实上,我不知道我们可以使用&gt;&gt; 运算符将字符串从十六进制转换为其他类型。顺便说一句,&gt;&gt; 转换似乎可以与右侧参数一起使用,因此它需要尽可能多的字节,因为它们适合参数:8、16、32、64 位。【参考方案2】:

感谢曼努埃尔的回答。这是解决问题的一种方法。我仍然想知道是否有更优雅的方式来做到这一点。

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

int main()

    cout << "Hello world!" << endl;

    // example 1: making a hex string an int - works
    std::stringstream str1;
    std::string s1 = "5f";
    str1 << s1;
    int value1;
    str1 >> std::hex >> value1;
    cout << "value 1 as int: " << value1 << endl; // produces 95 int - OK but an int
    uint8_t value2;
    value2 = (uint8_t)value1;
    cout << "value 2 as uint8: " << (int)value2 << endl; // produces 01011111 = 95 or '-' - correct

    return 0;

产生:

Hello world!
value 1 as int: 95
value 2 as uint8: 95

Process returned 0 (0x0)   execution time : 0.022 s
Press any key to continue.

【讨论】:

std::string s = "5f0066"; int num = std::stoi(s, 0, 16);16 您要转换的基础。还有other 转换为更长的值。

以上是关于如何将 stringstream 十六进制字符串字符对转换为单个 uint8_t 等效二进制值的主要内容,如果未能解决你的问题,请参考以下文章

如何使用字符串流格式化十六进制数字

在 C++ 中将十六进制字符转换为 int

如何使用 stringstream 在 C++ 中将字符串转换为双精度值 [关闭]

c ++,stl。将带有rgb颜色的字符串转换为3个int值?

使用 ostringstream 或 stringstream 将 C++ Int 转换为字符串

使用 stringstream 将字符串转换为 int