简体   繁体   中英

how to convert an ostringstream hex string character pairs to a single unit8_t equivalent binary value

I am trying to do the following:

I have an assembled ostringstream object that contains a hex payload to be transmitted. Say, it might be

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

This string is representing 11 bytes, so for example the last byte to be transmitted is 0xaf (two characters giving me 8 bits of actual data).

I wish to read each pair of characters, for example the '03' pair of characters in the string and convert that into a uint8_t element which I will push onto a vector of uint8_t elements. Essentially I will create a new vector of uint8_t elements based on the contents of the string, then transmit the vector.

My test program below works OK for 'int' but does not give me what I want for uint8_t. Is there an elegant and/or straightforward way to do what I am trying to do that anyone can suggest?

(Note: example 3 was to see what happens if a non-hex-legal value was used. In example 1, a value like 34r0 would convert 34(hex) to an equivalent int and ignore the r and everything following it).

#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;
}

The output from this test program looks like the below:

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

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

Example 1 works OK, but using int - this is not what I need.

In example 2 you are extracting a uint8_t , 8 bits, so one char from the string, the 5 .

In example 3 is the same, you extract the first char, so the w .

For the last example, it prints a char (8 bits), 95 is the ASCII - character. If you want to show the number, cast the value to int .

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

Thanks to Manuel for his answer. This is one way to solve the problem. I'd still like to know if there is a more elegant way to do this.

#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;
}

Which produces:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM