-1

So basically , I want to create a function that

takes this hex pattern:

"03 C6 8F E2 18 CA 8C E2 94 FD BC E5 03 C6 8F E2"

and returns this array of bytes:

BYTE pattern[] = { 0x03, 0xC6, 0x8F, 0xE2, 0x18, 0xCA, 0x8C, 0xE2, 0x94, 0xFD, 0xBC, 0xE5, 0x03, 0xC6, 0x8F, 0xE2 };

My main problem is what i need like each 0x03 in one byte cell, of the output array exactly as i described,

if i use this

   #include <windows.h>

    std::vector<BYTE> strPatternToByte(const char* pattern, std::vector<BYTE> bytes)
    {
        std::stringstream converter;
    
        std::istringstream ss( pattern );
        std::string word;
        while( ss >> word )
        {
            BYTE temp;
            converter << std::hex << "0x" + word;
            converter >> temp;
    
            bytes.push_back( temp );
        }
    
        return bytes;
    }
    
        int main()
        {
    
            const char* pattern = "03 C6 8F E2 18 CA 8C E2 D4 FD BC E5 03 C6 8F E2";
            std::vector<BYTE> bytes;
            bytes = strPatternToByte(pattern,bytes);
            BYTE somePtr[16];
            for ( int i=0 ; i < 16 ; i++)
            {
                somePtr[i] = bytes[i];
            }
    
    
            for(unsigned char i : somePtr)
            {
                std::cout << i << std::endl;
            }
            /*
             * output should be:
              0x03
              0xC6
              0x8F
             * etc
             * .
             * .
             */
    
            return 0;
    }

it doesn't actually do what i need because when i debug it , i look at the bytes vector and i see it puts 0 in a cell, x in a cell , 0 , in cell , 3 in cell , which is not what i want, is there anyway to solve this kind of problem ? the output aint like it should be, I added what the output should be there in the code something like this:

        /*
     * output should be:
      0x03
      0xC6
      0x8F
     * etc
     * .
     * .
     */

the somePtr array is my last output should be, with as i described up.

thanks.

J.Steve
  • 17
  • 9
  • 2
    What is `BYTE`? – cigien Sep 22 '20 at 13:20
  • I think BYTE is of size 8-bits. It needs to be at least 16-bits. – Harry Sep 22 '20 at 13:24
  • Its 8 bits as Harry said I guess.. – J.Steve Sep 22 '20 at 13:30
  • instead of BYTE, use uint16_t datatype. – Harry Sep 22 '20 at 13:31
  • In the vector? or in the array aswell? – J.Steve Sep 22 '20 at 13:33
  • thing is , i need it as BYTE, like the array output i described it has to be like that as I use it for something else after. – J.Steve Sep 22 '20 at 13:34
  • _Its 8 bits as Harry said I guess_ .. What does this mean? What have you defined `BYTE` to be? There is no data type with that name in standard C++. Is there any specific header which you have included to get `BYTE` type? – brc-dd Sep 22 '20 at 13:34
  • there is.. its just BYTE from #include – J.Steve Sep 22 '20 at 13:35
  • Instead of guessing what `BYTE` is, try making a [mre] – cigien Sep 22 '20 at 13:35
  • 2
    dup of https://stackoverflow.com/q/3221170/1216776 – stark Sep 22 '20 at 13:36
  • 1
    @J.Steve `` is not standard c++. There's no indication in the question that this header is being used. – cigien Sep 22 '20 at 13:36
  • Well sorry, didn't notice that will indicate in next questions and will edit my post – J.Steve Sep 22 '20 at 13:37
  • no these doesn't answer my question, that is output unsigned char array, my main purpose is to return BYTE array @stark this is not duplicate. – J.Steve Sep 22 '20 at 13:40
  • @molbdnilo changing BYTE temp to int temp doesn't solve anything.. – J.Steve Sep 22 '20 at 13:43
  • @MarekR no it doesn't – J.Steve Sep 22 '20 at 13:59
  • Can you guys read at least what im requesting before posting random answers and saying duplicate or different outputs, this aint no race.. – J.Steve Sep 22 '20 at 14:06
  • Have you actually tried the solutions people have given you? Because when I look in the [Windows API documentation](https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types) it says: BYTE - This type is declared in WinDef.h as follows: `typedef unsigned char BYTE;` So, it seems a bit odd that a solution that gives `unsigned char` don't work for you. – Frodyne Sep 22 '20 at 14:10

3 Answers3

3
template <typename T>
std::vector<uint8_t> bytesFromHex(std::basic_istream<T>& stream, size_t reserve = 0x100)
{
    std::vector<uint8_t> result;
    result.reserve(reserve);
    auto flags = stream.flags();
    stream.setf(std::ios_base::hex, std::ios_base::basefield);
    std::copy(std::istream_iterator<unsigned>{stream}, {}, std::back_inserter(result));
    stream.flags(flags);
    return result;
}

template <typename T>
std::vector<uint8_t> bytesFromHex(std::basic_string_view<T> s, size_t reserve = 0x100)
{
    std::basic_istringstream<T> stream{std::basic_string<T>{s}};
    return bytesFromHex(stream, reserve);
}

https://godbolt.org/z/aW915b

Marek R
  • 32,568
  • 6
  • 55
  • 140
  • Doesn't give the same output as im asking for.. and giving error on the basic_string_view part aswell – J.Steve Sep 22 '20 at 14:03
  • I used C++17, but it is easy to tweak this to older version (trash string_view). Anyway use godbolt to show what is your issue, on my example it works like charm. – Marek R Sep 22 '20 at 14:15
  • https://godbolt.org/z/a1Wen4 – Marek R Sep 22 '20 at 14:31
2

You have a number of minor errors.

By reusing your converter object it no longer works after the first conversion because it gets into an error state. Try this version that recreates the stringstream each time round the loop (you could also call converter.clear(); at the end of the loop).

while (ss >> word)
{
    int temp;
    std::stringstream converter;
    converter << std::hex << "0x" + word;
    converter >> temp;
    bytes.push_back(temp);
}

Also temp should be an int (you are reading integers after all).

The output loop is wrong, try this

 for (int i : somePtr)
 {
     std::cout << "0x" << std::hex << std::setfill('0') << std::setw(2) << i << std::endl;
 }

Again note that i is an int, and I've added formatting to get the effect you wanted. You will need to #include <iomanip>

john
  • 85,011
  • 4
  • 57
  • 81
  • Thank you now i understand what was wrong, this is actually the correct solution worked well for me. good job – J.Steve Sep 22 '20 at 14:20
0
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

typedef unsigned char BYTE; // Remove this line if you've included windows.h

std::vector<BYTE> strPatternToByte(std::string hex_chars) {
    std::istringstream hex_chars_stream(hex_chars);
    std::vector<BYTE> bytes;
    unsigned c;
    hex_chars_stream >> std::hex;
    while (hex_chars_stream >> c) bytes.push_back(c);
    return bytes;
}

int main() {
    std::string hex_chars = "03 C6 8F E2 18 CA 8C E2 D4 FD BC E5 03 C6 8F E2";
    auto bytes = strPatternToByte(hex_chars);
    std::cout << std::setfill('0') << std::hex << std::uppercase;
    for (unsigned i : bytes) std::cout << "0x" << std::setw(2) << i << '\n';
}

Output :

0x03
0xC6
0x8F
0xE2
0x18
0xCA
0x8C
0xE2
0xD4
0xFD
0xBC
0xE5
0x03
0xC6
0x8F
0xE2
brc-dd
  • 10,788
  • 3
  • 47
  • 67
  • You put the 0x in the cout at main, i need that to be in the actual byte array like i asked in the output up, and the vector bytes here u return is not like what i asked, it has integers, not 0x03, 0xC6 actually but u added them in the main.. – J.Steve Sep 22 '20 at 14:16
  • @J.Steve You cannot have `0x03` in the returned vector. In it each element is of 1 byte. With 1 byte it is impossible to store `0x03` in formatted form it will be stored internally as just `3`, similarly `0xC6` will just be `198` in the vector. – brc-dd Sep 22 '20 at 14:19