Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I combine multiple char reads into a std::vector?

Tags:

c++

I'm reading multiple reports from a HID device into an unsigned char, then trying to copy the data to a std::vector. I'm also writing the data out to a file for hex analysis, whose content appears to be correct when I view it. However, the std::vector doesn't appear to contain the correct data when I dump it to the console.

This is the code:

typedef vector<unsigned char> buffer_t;

buffer_t sendCommand (hid_device *devh, const unsigned char cmd[], int reports) {
    unsigned char outbuf[0x40];
    buffer_t retbuf(0x40 * reports);

    hid_write(devh, cmd, 0x41);

    int i;
    FILE *file = fopen("test.out", "w+b");
    while (i++ < reports) {
       hid_read(devh, outbuf, 0x40);
       fwrite(outbuf, 1, sizeof(outbuf), file);
       retbuf.push_back(*outbuf);
    }
    fclose(file);
    cout << &retbuf[0];
    return retbuf;
}

I have a feeling I'm way off the mark here; I'm fairly new to C/C++, and I've been stuck with this for a while now. Can anyone tell me what I'm doing wrong, or point me in a better direction?

like image 529
Andy E Avatar asked Mar 10 '26 02:03

Andy E


1 Answers

You want to add multiple unsigned char objects to your vector, but push_back only adds one.

So, replace retbuf.push_back(*outbuf); with either:

for (size_t i = 0; i < sizeof(outbuf); ++i) {
    retbuf.push_back(outbuf[i]);
}

or

std::copy(outbuf, outbuf+sizeof(outbuf), std::back_inserter(retbuf));

or

retbuf.insert(retbuf.end(), outbuf, outbuf+sizeof(outbuf));

which all do the same thing.

You create your vector with a certain size:

buffer_t retbuf(0x40 * reports);

but push_back increases the size of the vector by adding an element at the end. You should create it empty:

buffer_t retbuf;

Optionally, you could arrange for the vector to have enough space allocated, ready for the elements you're going to add:

retbuf.reserve(0x40 * reports);

This is purely a performance issue, but sometimes it's a significant issue for large vectors, or vectors of types that (unlike unsigned char) are expensive to copy/move when the vector runs out of internal space and has to allocate more.

A note on style: you repeat the literal value 0x40 a few times, and also use sizeof(outbuf). It's often best to define a constant, and use the name throughout:

const int report_size = 0x40;

This is partly in case the number changes in future, but also it's about the readability of your code -- if someone sees 0x40 they may or may not immediately understand why that is the correct value. If someone sees report_size then they don't know what value that actually is until they look it up, but they do know why you're using that value.

like image 164
Steve Jessop Avatar answered Mar 11 '26 15:03

Steve Jessop