How to save Hex value characters from char array elements to a char array, TCHAR, LPCTSTR, and CString?

52 views Asked by At

How to I take the byte hex values from each element, and save each hex character to a char array, TCHAR, LPCTSTR, and CString?

Yes, I know that some of these are close to or functionally the same thing, but I have to save and manipulate the data a few different ways and will need these datatypes. If that make this a little too broad, for the sake of limiting this question to my immediate purposes, one of my needs is to take packet data I collected to a char array and output it as Hex to a List on my MFC application (SetItemText(int, int, LPCTSTR)). But I imagine much of the process is similar or the same, and I would appreciate the help with the other datatypes.

I have search around and tried several methods involving stringstreamHERE , sprintf HERE , and a few others. The most I was able to output was the data array's memory location (not the data itself). The rest resulted in garbage characters, nothing, or the wrong data... and even then, the >10 zeros were not present. I'm sure the error is with my implementation, so I'm here for a focused use case. Below is a framework of what I'm looking for.

void SaveCharArrayHexData(struct &output, int index)
{
    char data[4] = {'0x07', '0x13', '0xF4', '\0'};

    //Get byte hex values from data
    //Assign each Hex character to datatypes as individual characters, including >10 zeros.
    //Example: 
    //        INPUT: data={'0x07', '0x13', '0xF4', '\0'}  size = 3
    //       OUTPUT: outputCharArray={'0', '7', '1', '3', 'F', '4', '\0'}  size = 6

    //output.outputCharArray = ?
    //output.outputLPCTSTR = ?
    //output.outputTCHAR = ?
    //output.outputCString = ?

    m_list.SetItemText(index, 0, outputLPCTSTR);

} 
2

There are 2 answers

4
Christian Stieber On

Not entirely sure I even got your question right; it seems... too trivial.

I usually avoid sprintf and streams and whatnot for such trivial tasks.

To convert a single char to two hex characters, just do something like this:

char hexDigit(unsigned char value)
{
   if (value<=9) return '0'+value;
   assert(value<=15);
   return 'a'-10+value;
}

void toHex(char input, std::string& output)
{
   output+=hexDigit(static_cast<unsigned char>(input)>>4);
   output+=hexDigit(input&0x0f);
}

Note: this only works on computers that use ASCII-based character encodings. Or 100% of the machines you'll encounter these days, unless you're doing software for old mainframes that might still be using EBCDIC. Alternative version:

char hexDigit(unsigned char value)
{
   assert(value<=15);
   return "0123456789abcdef"[value];
}

toHex() just appends the two digits to the output string. You can do something like this:

#include <string>
#include <iostream>
#include <cassert>

// code from above goes here

int main(void)
{
    char data[] = {0x07, 0x13, 0xF4};
    std::string result;
    for (char c: data)
    {
        if (!result.empty()) result+=", ";
        toHex(c, result);
    }
    std::cout << result << '\n';
    return 0;
}

Test run:

stieber@gatekeeper:~ $ g++ Test.cpp && ./a.out
07, 13, f4

Adapt the general idea to whatever datatypes you actually want to use.

0
273K On

The links you referenced are solving the task.

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <sstream>

int main() {
  unsigned char data[4] = {0x07, 0x13, 0xF4, 0};
  std::stringstream ss;

  // This is all what you need.
  std::copy(std::begin(data), std::prev(std::end(data)),
            std::ostream_iterator<int>(ss << std::setfill('0') << std::setw(2)
                                          << std::hex));

  const auto& outputCharArray = ss.str();
  std::cout << outputCharArray << "\n";
  std::cout << "size: " << outputCharArray.size() << "\n";
}
// 0713f4
// size: 6

Known issue:

unsigned char data[4] = {0x07, 0x03, 0xF4, 0};
// 073f4
// size: 5

fixed here "Permanent" std::setw or with using a range loop.