-1

I am using a C++ code to read some binary output from an electronic board through USB. The output is stored on an unsigned char buffer. When I'm trying to print out the value or write it to an output file, I get dummy output instead of hex and binary value, as shown here:

햻"햻"㤧햻"㤧햻"햻"㤧

This is the output file declaration:

f_out.open(outfilename, ios::out);
if (false == f_out.is_open()) {
    printf("Error: Output file could not be opened.\n");
    return(false);
}

This is the output command:

xem->ReadFromPipeOut(0xA3, 32, buf2);
f_out.write((char*)buf2, 32);
//f_out << buf2;

"xem" is a class for the USB communication. ReadFromPipeOut method, reads the output from the board and stores it on the buffer buf2. This is the buffer definition inside the main:

unsigned char buf2[32];
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055

1 Answers1

2

Why do you expect hex output? You ask to write chars, it writes chars.

To output hex values, you can do this:

f_out << std::hex;
for (auto v : buf2)
    f_out << +v << ' ';

To get numbers in the output, values should be output as integers, not as characters. +v converts unsigned char into unsigned int thanks to integral promotion. You can be more explicit about it and use static_cast<unsigned int>(v).

unsigned char buf[3] = {0x12, 0x34, 0x56};
std::cout << std::hex;
for (auto v : buf)
    std::cout << static_cast<unsigned int>(v) << ' ';
// Output: 12 34 56

To output numbers as binary:

for (auto v : buf)
    std::cout << std::bitset<8>(v) << ' ';

(no need for std::hex and static_cast here)

To reverse the order:

for (auto it = std::rbegin(buf); it != std::rend(buf); ++it)
    std::cout << std::bitset<8>(*it) << ' ';

Note that the order of bytes in a multi-byte integer depends on endian-ness. On a little-endian machine the order is reserved.

Evg
  • 25,259
  • 5
  • 41
  • 83
  • Thanks a lot for your reply! I am not expecting hex, the output is simply binary but I was a bit shocked by the output. I want to read the same binary output without any changing by converting. Is there a way to print the output in binary? Many thanks – MHD Anas Alsakkal Dec 29 '19 at 12:42
  • Also, the output is reversed! Like the input, for example, is: 1 27 31 4 156, the output is printed as 156 4 31 27 1! is there a way to fix this as well? thanks – MHD Anas Alsakkal Dec 29 '19 at 13:44
  • I used the following for binary printing: std::cout << std::hex; for (auto v : buf2) f_out << bitset<8>(static_cast(v)) << endl; However, the numbers are reversed! – MHD Anas Alsakkal Dec 29 '19 at 14:11
  • @MHDAnasAlsakkal, the loop itself does not reverse the output, but it might be reversed due to endian-ness, for example. – Evg Dec 29 '19 at 14:12
  • yes I mean ones and zeros within each number. As I said, if the output should be: 1 2 3 4, the printed output is : 4 3 2 1 – MHD Anas Alsakkal Dec 29 '19 at 14:17
  • The order is reversed in `buf2` already. You can reverse the output manually. See the updated answer. – Evg Dec 29 '19 at 14:19
  • 1
    This is perfect!! It works properly with reversing the bit order. Many thanks ^_^ . – MHD Anas Alsakkal Dec 29 '19 at 14:24
  • Thanks a lot for perfectly editing the answer : ) However, I have just noticed that actually the reversed bit solution gets the first 4 bytes wrong! but the rest are correct, any idea? – MHD Anas Alsakkal Dec 29 '19 at 15:01
  • @MHDAnasAlsakkal, maybe you need to reverse them in blocks of `N` bytes. But it depends on how data in `buf` is organized. – Evg Dec 29 '19 at 15:14
  • In fact on a large data input this effect becomes clear and the data is highly corrupted! the data is actually organised as 4 bytes numbers. every 4 bytes form a 2's complement number. – MHD Anas Alsakkal Dec 29 '19 at 15:17
  • @MHDAnasAlsakkal Then you need to reverse them in `4`-bytes block, I guess. – Evg Dec 29 '19 at 15:20
  • When the natural order is used, the output data seems to be exactly as expected. but it is reversed as I explained. However, when the reversed order is used, yes most of the data flipped correctly, but some strange numbers appears! is there another way of getting the reverse done? many thanks – MHD Anas Alsakkal Dec 29 '19 at 15:55
  • @MHDAnasAlsakkal It is hard to guess without seeing some example. There is no magic universal way. It depends on how your data is organized. – Evg Dec 29 '19 at 16:00
  • with normal order: Expect output: 00000000001000101101010110111011 Actual output : 10111011110101010010001000000000 You can notice that the forth byte should be first, third should be second and so on. with reverse order: Expect output: 00000000001000101101010110111011 Actual output : 00000000001000101101010110111011 (same) – MHD Anas Alsakkal Dec 29 '19 at 16:21
  • However, the first value is: 00000000000101110011100100100111 which is not expected at all. In this example I set the buffer size to 32, and I move the data on multiple iterations. As the buffer size increases, the data becomes more corrupted. As the size of this example is 32 and every 4 bytes form a number in my data, after 8 numbers when the buffer gets new data, some values are also missing. So, it also hard to explain the behaviour of the reverse method. Thanks – MHD Anas Alsakkal Dec 29 '19 at 16:21
  • @MHDAnasAlsakkal, this problem has nothing to do with the output itself. I suggest you ask another question with more details about the problem. – Evg Dec 29 '19 at 17:06
  • OK, I'll post another question. Thanks a lot for your help! – MHD Anas Alsakkal Dec 29 '19 at 17:10
  • I have got it work by swapping the bytes this way: xem->ReadFromPipeOut(0xA3, 32, buf2); int i = 1; for (auto v : buf2) { if (i == 1) { v4 = v; } if (i == 2) { v3 = v; } if (i == 3) { v2 = v; } if (i == 4) { f_out << bitset<8>(v) << bitset<8>(v2) << bitset<8>(v3) << bitset<8>(v4) << endl; i = 0; } i++; } – MHD Anas Alsakkal Dec 29 '19 at 17:49