Formatted output

K

keith

I've been beating my head against this for a little while, so perhaps
someone can help me out here? The code below should output exactly as
follows (the hex data lines up in a fixed font):

DATA 0123456789abcdef0123456789abcdef
0123456789abcdef0123456789abcdef

and the code does indeed do that when I use the fprintf() call. When
I comment that line out and use the iostream line, I get gibberish. I
guess I'm just not 'getting' C++ formatted I/O yet.

Here's the code, for what it's worth:

#include <cstdio>
#include <iostream>
#include <iomanip>

static void
output(const std::string& s, unsigned char* buf, const size_t len)
{
std::cerr << s << ' ';
for (unsigned int i = 0; i < len; ++i)
{
int j = (i+1) % 16;
// std::cerr << std::setw(2) << std::ios::hex << buf; // no good
fprintf(stderr, "%02x", buf); // works fine
if ((i+1) < len && j == 0)
std::cerr << '\n' << std::setw(s.size()) << ' ';
}
std::cerr << '\n';
}

int main()
{ unsigned char data[] =
{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};

output("DATA", data, 32);
exit(0);
}
 
O

Ondra Holub

I've been beating my head against this for a little while, so perhaps
someone can help me out here? The code below should output exactly as
follows (the hex data lines up in a fixed font):

DATA 0123456789abcdef0123456789abcdef
0123456789abcdef0123456789abcdef

and the code does indeed do that when I use the fprintf() call. When
I comment that line out and use the iostream line, I get gibberish. I
guess I'm just not 'getting' C++ formatted I/O yet.

Here's the code, for what it's worth:

#include <cstdio>
#include <iostream>
#include <iomanip>

static void
output(const std::string& s, unsigned char* buf, const size_t len)
{
std::cerr << s << ' ';
for (unsigned int i = 0; i < len; ++i)
{
int j = (i+1) % 16;
// std::cerr << std::setw(2) << std::ios::hex << buf; // no good
fprintf(stderr, "%02x", buf); // works fine
if ((i+1) < len && j == 0)
std::cerr << '\n' << std::setw(s.size()) << ' ';
}
std::cerr << '\n';

}

int main()
{ unsigned char data[] =
{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};

output("DATA", data, 32);
exit(0);

}


Try
std::cerr << std::setw(2) << std::ios::hex << (int)buf;
 
Z

Zeppe

I've been beating my head against this for a little while, so perhaps
someone can help me out here? The code below should output exactly as
follows (the hex data lines up in a fixed font):

DATA 0123456789abcdef0123456789abcdef
0123456789abcdef0123456789abcdef

and the code does indeed do that when I use the fprintf() call. When
I comment that line out and use the iostream line, I get gibberish. I
guess I'm just not 'getting' C++ formatted I/O yet.

Here's the code, for what it's worth:

#include <cstdio>
#include <iostream>
#include <iomanip>

static void
output(const std::string& s, unsigned char* buf, const size_t len)
{
std::cerr << s << ' ';
for (unsigned int i = 0; i < len; ++i)
{
int j = (i+1) % 16;
// std::cerr << std::setw(2) << std::ios::hex << buf; // no good


That's your magic line:
std::cerr << std::setfill('0') << std::setw(2) << std::hex <<
static_cast<unsigned>(buf) << std::setfill(' ');

Regards,

Zeppe
 
R

Robert Bauck Hamar

I've been beating my head against this for a little while, so perhaps
someone can help me out here? The code below should output exactly as
follows (the hex data lines up in a fixed font):

DATA 0123456789abcdef0123456789abcdef
0123456789abcdef0123456789abcdef

and the code does indeed do that when I use the fprintf() call. When
I comment that line out and use the iostream line, I get gibberish. I
guess I'm just not 'getting' C++ formatted I/O yet.

Here's the code, for what it's worth:

#include <cstdio>
#include <iostream>
#include <iomanip>

static void
output(const std::string& s, unsigned char* buf, const size_t len)
{
std::cerr << s << ' ';
for (unsigned int i = 0; i < len; ++i)
{
int j = (i+1) % 16;
// std::cerr << std::setw(2) << std::ios::hex << buf; // no good


First:
std::ios::hex is a constant. It's a flag, but this code just outputs the
number. Sending std::hex instead of std::ios::hex will fix this.
Second:
buf is an unsigned char. Outputting it will call the overload for
unsigned char output. An explicit conversion to unsigned int would fix
this.

So:
std::cerr << std::setw(2) << std::hex << unsigned(buf);
fprintf(stderr, "%02x", buf); // works fine


If you're lucky. <cstdio> declares std::fprintf, and may declare ::fprintf.
You could say:
using std::fprintf;
to fix this issue. Or just use std::fprintf.
if ((i+1) < len && j == 0)
std::cerr << '\n' << std::setw(s.size()) << ' ';
}
std::cerr << '\n';
}

int main()
{unsigned char data[] =
{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};

output("DATA", data, 32);
exit(0);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top