convert string to hex

Hello all ,

Please how can convert this string to hex ..

string packet = "11101111000001010110000";
Last edited on
There's (at least) two ways of doing it. Either parse each bit, convert to int, and then convert that int to hex (e.g. std::hex format, see <iomanip>).

Or, if you want to keep yourself in string land: Every 4 bits == 1 hex-char, because a hex-char is 4-bit (0 through F). Zero-pad the string so that it's a multiple of 4, then use packet.substr with a for loop to isolate each group of 4, and if "0000" --> output "0", if "0001" --> output "1", if "1010" --> output "A", etc.

Example to get your started:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
using std::string;

int main()
{
    string packet = "11101111000001010110000";
    
    const int BitsPerHex = 4;
    
    size_t padding_needed = (BitsPerHex - (packet.size() % BitsPerHex)) % BitsPerHex;
     
    std::cout << "length: " << packet.length() << ", padding needed: " <<  padding_needed << '\n';
    
    packet = std::string(padding_needed, '0') + packet;

    for (size_t i = 0; i < packet.length(); i += BitsPerHex)
    {
        std::string hexchar_str = packet.substr(i, BitsPerHex);
        std::cout << hexchar_str << '\n';
    }
}

length: 23, padding need: 1
0111
0111
1000
0010
1011
0000
Last edited on
As hex for display, as a hex string or?? It's easy to convert to a number and then display that number as hex:

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <bitset>
#include <string>
#include <iomanip>

int main() {
	const std::string packet { "11101111000001010110000" };

	std::cout << "0x" << std::hex << std::setw(8) << std::setfill('0') << std::bitset<32>{packet}.to_ulong() << '\n';
}


which displays:


0x007782b0


But if you want it as a hex string, then:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <bitset>
#include <string>
#include <iomanip>
#include <sstream>

int main() {
	const std::string packet { "11101111000001010110000" };
	std::ostringstream oss;

	oss << std::hex << std::setw(8) << std::setfill('0') << std::bitset<32>{packet}.to_ulong();

	const auto asHex { oss.str() };

	std::cout << asHex << '\n';
}


Thanks fro replay Ganado ,seeplus
Thank you very much for your great effort ,

all example is good and work .

Please i want add this hex (7782b0) in my array

Example:
const unsigned char Sendbuff[] = {0x10,0x00,0xD6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x82,0xb0};



Thanks ..
You don't need it in hex then, you just need to convert it to a series of 8-bit ints.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <string>
#include <vector>
using std::string;

int main()
{
    string packet = "11101111000001010110000";
    
    using byte = unsigned char;
    std::vector<byte> bytes;

    const int BitsPerByte = 8;
    size_t padding_needed = (BitsPerByte - (packet.size() % BitsPerByte)) % BitsPerByte;
    packet = std::string(padding_needed, '0') + packet;

    for (size_t i = 0; i < packet.length(); i += BitsPerByte)
    {
        // binary to int
        byte sum = 0;
        for (size_t j = 0; j < BitsPerByte; j++)
        {
            sum = sum * 2;
            
            if (packet[i + j] == '1')
            {
               sum += 1;
            }
        }

        bytes.push_back(sum);
    }
    
    for (byte b : bytes)
    {
        std::cout << (int)b << '\n';   
    }
}

119
130
176


(The representation of the number printed is immaterial; at the end of the day, 1s and 0s are transmitted.)
Last edited on
Thanks so much ,


i need it in hex ,
like this example :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <bitset>
#include <string>
#include <iomanip>
#include <sstream>

int main() {
	const std::string packet { "11101111000001010110000" };
	std::ostringstream oss;

	oss << std::hex << std::setw(8) << std::setfill('0') << std::bitset<32>{packet}.to_ulong();

	const auto asHex { oss.str() };

	std::cout << asHex << '\n';
}


Output : 007782b0
i want add this hex (7782b0) in my array
Example:
const unsigned char Sendbuff[] = {0x10,0x00,0xD6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x82,0xb0,0x00};
So, to be clear, your goal is to have a program that generates C++ code, which will then be fed into another compiler?

You have the string as hex. Show us your attempt at what you want to do, and tell us specifically what is giving you trouble.
Last edited on
Thanks for replay Ganado ,One step left and the problem will be solved
My code :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <bitset>
#include <string>
#include <iomanip>
#include <sstream>
#include <algorithm>
#include <limits>
using namespace std;
string s = "";
void decToBinary(unsigned packet) {
	 std::bitset<21> d{packet} ;
	 cout << d <<endl;
	 s = d.to_string();

}
// Function to remove the leading zeros
string removeLeadingZeros(string num)
{
    // traverse the entire string
    for (int i = 0; i < num.length(); i++) {
 
        // check for the first non-zero character
        if (num[i] != '0') {
            // return the remaining string
            string res = num.substr(i);
            return res;
        }
    }

    return "0";
}
int main()
{
    
  decToBinary(1950000);
  s.insert (s.end() - 7,1,'1');
  s.insert (s.end() - 14,1,'0');
  string g = "1";
  int i{s.size()};
  int rep =  i - 16;
  s.replace(rep, 1,g); 
  std::ostringstream oss;
  oss << std::hex << std::setw(8) << std::setfill('0') << std::bitset<32>{s}.to_ulong();
  const auto asHex { oss.str() };


   string removzero = removeLeadingZeros(asHex);
	
     string r1 = removzero.substr(0, 2);
     string r2 = removzero.substr(2, 2);
     string r3 = removzero.substr(4, 2);
     
  std::cout << removzero << '\n';
  std::cout << r1 << '\n';
  std::cout << r2 << '\n';
  std::cout << r3 << '\n';

const unsigned char Sendbuff[] = {0x10,0x00,0xD6,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  return 0;
}


all i need add r1 ,r2 r3 to this array (Sendbuff) .
Few things,

(1) There is no reason to have 's' as a global variable. You could have decToBinary return a string. (Also, the variable name 's' is not informative at all.)

(2) having variables like 'i' used as anything other than a simple iteration variable is not recommended.

(3) Line 39's curly braces are illegal here because s.size() is losing information when converting to int.

(4) the logic happening here is very roundabout. You're starting off with an int, then converting it into binary, then converting it into hex, then trying to convert it back into an int (unsigned char).

The actual logic happening seems to be lines 36, 37. What is their purpose? What does 1950000 mean? (What I'm asking is, what is the format/data type and range in values of the true input to your system?)

Anyway... long story short: Your code could be simplified.

But, just to get this working:

1
2
3
4
5
6
7
8
9
10
// https://stackoverflow.com/questions/1070497/c-convert-hex-string-to-signed-integer
unsigned char hex_to_byte(const std::string& hex)
{
    unsigned int output; 
    std::stringstream ss;
    ss << std::hex << hex;
    ss >> output;
    
    return output;
}



1
2
3
4
5
6
7
8
9
10
11
  std::cout << removzero << '\n';
  std::cout << r1 << '\n';
  std::cout << r2 << '\n';
  std::cout << r3 << '\n';
  
  unsigned char byte_r1 = hex_to_byte(r1);
  unsigned char byte_r2 = hex_to_byte(r2);
  unsigned char byte_r3 = hex_to_byte(r3);


  unsigned char Sendbuff[] = {0x10,0x00,0xD6,0x00,0x00,0x00,0x00,0x00,0x00,0x00, byte_r1, byte_r2, byte_r3};



Last edited on
if you are doing a great quantity of conversion, and it looks like you might, a lookup table of the text against an ascii table (256 entries) is notably faster than the built in conversions which have a lot of unnecessary stuff in them (like conditions for whether to use upper or lower case A-F). Its premature optimization, but keep it in mind if the issue comes around.
Last edited on
Do you mean something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <bitset>
#include <string>
#include <iomanip>
#include <sstream>

std::string decToStr(unsigned packet) {
	return std::bitset<21> { packet }.to_string();
}

std::string alter(std::string s) {
	s.insert(s.end() - 7, 1, '1');
	s.insert(s.end() - 14, 1, '0');
	s.replace(s.size() - 16, 1, "1");

	return s;
}

int main() {
	constexpr unsigned dec { 1950000 };
	constexpr unsigned startpos { 10 };
	constexpr unsigned noBytes { 3 };
	constexpr unsigned sizeBuff { 13 };

	unsigned char Sendbuff[sizeBuff] { 0x10,0x00,0xD6 };
	std::stringstream oss;

	oss << std::hex << std::setw(2 * noBytes) << std::setfill('0') << std::bitset<8 * noBytes> { alter(decToStr(dec)) }.to_ulong();
	oss.seekg(0);

	for (unsigned i {}; i < noBytes; ++i) {
		std::string x;

		oss >> std::hex >> std::setw(2) >> x;
		Sendbuff[startpos + i] = static_cast<unsigned char>(std::stoul(x, nullptr, 16));
	}

	for (unsigned i : Sendbuff)
		std::cout << std::hex << i << ' ';

	std::cout << '\n';
}


which displays:


10 0 d6 0 0 0 0 0 0 0 77 82 b0

thanks so much Ganado , Working good

Thanks for the notes jonnin

thanks so much seeplus , good example

solved




Last edited on
Topic archived. No new replies allowed.