1

I read a file and transform it to hex notation like this {0x4D,x0FF,0x01} I stock it in an unsigned char array. I can print what I would like to stock but I don't achieve to stock datas in my array. I read the bitset class documentation but I am not sure that it is what I need. According to this source code, how can I stock datas read to have the same result as that :

unsigned char array[3] = {0x4D,x0FF,0x01};

Note that the vector don't have the good notation, this is reason why I use setfill and setw.

    size = file.tellg();
    unsigned char* rawData = new unsigned char[size];
    memblock = new uint8_t[size];
    std::vector<uint8_t> memblock(size);
    file.seekg(0, ios::beg);
    file.read(reinterpret_cast<char*>(memblock.data()), size);
    file.close();
    for (int i = 0; i < size; i = i++)
    {
        if (i == (int)size - 1)
        {
            cout << "0x" << setfill('0') << setw(2) << std::hex << (unsigned)memblock.at(i);
        }
        else
        {
            cout << "0x" << setfill('0') << setw(2) << std::hex << (unsigned)memblock.at(i) << ",";
        }

    }

Edit : This is my actual code :

    unsigned char* rawData[1] = {0x00}; // My rawData in out of function.

 void readFile(std::string p_parametre, unsigned char* rawData[])
{
    std::ifstream input{ p_parametre, std::ios::binary };
    if (!input.is_open()) {  // make sure the file could be opened
        std::cout << "Error: Couldn't open\"" << p_parametre << "\" for reading!\n\n";
    }

    // read the file into a vector
    std::vector<unsigned char> data{ std::istream_iterator<unsigned char>{ input },
                                     std::istream_iterator<unsigned char>{} };

    std::ostringstream oss;  // use a stringstream to format the data

                                 // instead of the glyph
    for (int i = 0; i < data.size(); i++)
    {
        if (i == i- 1)
        {
            oss <<'0'
                << 'x'
                << std::setfill('0') << std::setw(2) << uppercase << std::hex << static_cast<int>(data.at(i));
        }
        else
        {
            oss << '0'
                << 'x'
                << std::setfill('0') << std::setw(2) << uppercase << std::hex << static_cast<int>(data.at(i)) << ',';
        }

    }

    // create a unique_ptr and allocate memory large enough to hold the string:
    std::unique_ptr<unsigned char[]> memblock{ new unsigned char[oss.str().length() + 1] };

    // copy the content of the stringstream:
    int r = strcpy_s(reinterpret_cast<char*>(memblock.get()), oss.str().length() + 1, oss.str().c_str());

    OpenFile(memblock.get());
    getchar();
}
  • You don't "transform" anything, you simply read the files bytes into the vector `memblock`. "I can print what I would like to stock but I don't achieve to stock datas in my array." What do you mean by stock data? Do you want a string representing each byte as a hex number? – Swordfish Sep 28 '18 at 20:13
  • _Do you want a string representing each byte as a hex number?_ Exact, I would like each byte as hex in my unsigned string array. – Timtim45687 Sep 28 '18 at 20:24
  • See my updated answer. – Swordfish Sep 28 '18 at 20:37
  • @Swordfish, Thank for your answer but I need absolutely to fill in the rawData variable which is type of unsigned int[] because I have some constraints behind. Also, strcpy is deprecated as Visual Studio 2017. – Timtim45687 Sep 29 '18 at 12:17
  • `memblock.get()` **is** a `unsigned int[]` aka `unsigned int *`. "Also, strcpy is deprecated as Visual Studio 2017." well, use `std::strncpy()`? I don't get a depreciated warning, though, and it is part of `std`. – Swordfish Sep 29 '18 at 12:23
  • I just edited my question to show you my actual code. If I use strcpy_s, I have a buffer size problem because `oss.str().length() > sizeof(memblock.get())`. I just want to fill in the rawData passed in parameter. Why it's so complicated to fill an unsigned char array... – Timtim45687 Sep 29 '18 at 18:09
  • ? What "size problem"? `sizeof memblock.get()` evaluates to the size of a pointer type (`unsigned char*`) on your system. – Swordfish Sep 29 '18 at 19:50
  • I just edited my question to show you a screenshot. – Timtim45687 Sep 30 '18 at 15:26
  • You are misusing `strcpy_s()`. "the following errors are detected at runtime and call the currently installed constraint handler function:: [...] `destsz` is less or equal `strnlen_s(src, destsz);` in other words, truncation would occur". You have to pass `oss.str().length() + 1`. – Swordfish Oct 01 '18 at 04:58
  • Hi, I already try to pass oss.str().length() + 1 and I have not the error but the problem is when I use my char tab to open my file as a ressource, the file is not recognized probably because bytes are broken. But, if I copy/past hex code directly as a ressource in my source code like that : unsigned char* rawData[3] = {0x00, 0xFF, 0x4D}; it works. Do you think I shouldn't convert my binary to hex notation ? I edited my question. – Timtim45687 Oct 01 '18 at 20:34
  • "when I use my char tab", "because bytes are broken." I have no idea what you are talking about. – Swordfish Oct 01 '18 at 20:40

1 Answers1

0
#include <cstdlib>
#include <vector>
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <iterator>
#include <memory>
#include <cstring>

int main()
{
    char const *input_filename{ "test.txt" };
    std::ifstream input{ input_filename, std::ios::binary };
    if (!input.is_open()) {  // make sure the file could be opened
        std::cout << "Error: Couldn't open\"" << input_filename << "\" for reading!\n\n";
        return EXIT_FAILURE;
    }

    // read the file into a vector
    std::vector<unsigned char> data{ std::istream_iterator<unsigned char>{ input },
                                     std::istream_iterator<unsigned char>{} };

    std::ostringstream oss;  // use a stringstream to format the data
    for (auto const &d : data)       // iterate over every element in vector data
        oss << std::setw(2)          // set the field-width to 2
            << std::setfill('0')     // fill up unused width with '0' instead space
            << std::hex              // output as hex number
            << static_cast<int>(d);  // cast the character to an int cause we
                                     // want to print the numeric representation
                                     // instead of the glyph

    // > Exact, I would like each byte as hex in my unsigned string array.

    // create a unique_ptr and allocate memory large enough to hold the string:
    std::unique_ptr<unsigned char[]> memblock{ new unsigned char[oss.str().length() + 1] };

    // copy the content of the stringstream:
    std::strcpy(reinterpret_cast<char*>(memblock.get()), oss.str().c_str());
}
Swordfish
  • 12,971
  • 3
  • 21
  • 43