Reputation: 143
In a program developed with C ++ on Linux I need to show the content of several arrays that contain bytes.
These arrays are declared as an array of characters.
I am trying to display its content with std::cout but I am not getting the output I need, lthough I have tried in several different ways.
I illustrate this with a simple program example:
#include <stdio.h>
#include <stdint.h>
#include <iostream>
#include <iomanip>
int main()
{
char data[10] = { 0 };
for (uint8_t i=0; i<10; i++)
data[i] = 5 + 2*i;
printf ("ONE: 0x%02X 0x%02X 0x%02X 0x%02X\n", data[2], data[3], data[4], data[5]);
std::cout << "TWO: " << std::setw(2) << std::hex << std::uppercase << std::left << std::setfill('0')
<< int(data[2]) << " " << int(data[3]) << " " << int(data[4]) << " " << int(data[5]) << std::endl;
std::cout << "THREE: "
<< std::setw(2) << std::hex << std::uppercase << std::left << std::setfill('0')
<< int(data[2]) << " "
<< std::setw(2) << std::hex << std::uppercase << std::left << std::setfill('0')
<< int(data[3]) << " "
<< std::setw(2) << std::hex << std::uppercase << std::left << std::setfill('0')
<< int(data[4]) << " "
<< std::setw(2) << std::hex << std::uppercase << std::left << std::setfill('0')
<< int(data[5]) << std::endl;
std::cout.setf(std::ios::hex | std::ios::left | std::ios::uppercase, std::ios::basefield);
std::cout.width(2);
std::cout.fill('0');
std::cout << "FOUR: " << int(data[2]) << " " << int(data[3]) << " "
<< int(data[4]) << " " << int(data[5]) << std::endl;
return 0;
}
The printf output is correct, it corresponds to the format I need:
ONE: 0x09 0x0B 0x0D 0x0F
The output I get in the TWO case is: TWO: 90 B D F The output I want to get is: TWO: 09 0B 0D 0F It presents the following errors:
The TRHEE case ensures that the output of each data is always two characters wide: THREE: 90 B0 D0 F0 The output I want to get is: THREE: 09 0B 0D 0F It presents the following errors:
The FOUR case shows: FOUR: 9 B D F The output I want to get is: FOUR: 09 0B 0D 0F It presents the following errors:
What is the correct way to use cout so that it shows 09 0B 0D 0F?
What should I change in the program?
Upvotes: 1
Views: 1056
Reputation: 4288
You want to align your characters to the right (std::right
) so that your fill character occupies everything to the left of it. std::setw
only applies to the next formatted output that can be modified by std::setw
, which means only the first datapoint will have a width of 2.
Note that std::right
is the default for a std::ostream
such as std::cout
, but I'm leaving it in here since the stream could be in an unknown state beforehand.
std::setfill
, std::left
, std::hex
can be set once and apply to the stream until they're reset. The best practice would be to save the current stream state, set it how you want, and then restore it when you're done. This is described in this answer https://stackoverflow.com/a/2273352/2027196
You want
// save stream format
std::ios_base::fmtflags f( cout.flags() );
// set format flags we want
std::cout << std::right << std::hex << std::uppercase << std::setfill('0');
// do actual output
std::cout << "THREE: "
<< std::setw(2) << int(data[2]) << " "
<< std::setw(2) << int(data[3]) << " "
<< std::setw(2) << int(data[4]) << " "
<< std::setw(2) << int(data[5]) << "\n";
// restore prior IO flags
cout.flags( f );
Upvotes: 4