1

I want to justify the output text like this

 0x29823d80    0x10019b8         /    0 00000000000000000000000000000001
 0x37449e60    0x10dfc           /   12 00000000000000000001000000000000

However with this statement

  fout << std::setw(5) << std::hex << "0x" << (*it).addr << " " 
       << std::setw(5) << std::hex << "0x" << (*it).pc << std::setw(10) << "/" << std::setw(5) << std::dec << (*it).off << "\t" 
       << std::setw(5) << (*it).layout << "\n";

I get this:

0x29823d80    0x10019b8         /    0  00000000000000000000000000000001
0x37449e60    0x10dfc         /   12    00000000000000000001000000000000 
mahmood
  • 23,197
  • 49
  • 147
  • 242

3 Answers3

5

From this reference:

This value is not "sticky": the next input or output operation that is affected by the value of the stream's width field, resets it to zero (meaning "unspecified").

This means that the setw you do is for the string "0x" and not the actual hex number. You have to use setw right before the output you want to justify.

Edit: One solution to your problem is to use temporary string containing the leading "0x", and the format with those string instead:

std::ostringstream val1, val2;

val1 << "0x" << std::hex << (*it).addr;
val2 << "0x" << std::hex << (*it).pc;

fout << val1.str() << " " << val2.str()
     << std::setw(10 + 10 - val2.str().length())
     << '/' ...

The expression 10 + 10 - val2.str().length() above I get from this:

  • The first 10 because you seem to want 10 spaces between the number and the slash
  • The second 10 because that allows for 8 hex digits (32 bits) plus the leading "0x"
  • Adjust for the actual length of the number string

You can see an example using this method here.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • But that may cause `0x` to be separated from the number. I mean with `setw(5)` we have `0x12345` and `0x 345` – mahmood Oct 31 '12 at 14:04
  • @mahmood Then you also need to adjust the padding depending on the number of digits for the hex number. Please see my modified answer. – Some programmer dude Oct 31 '12 at 14:24
1

I know this may not be what you are after, but remember that C is mostly a subset of C++, and that you in particular have the function fprintf available, which is much more suited for formatting simple strings and numbers than the C++ I/O facilities. With this, you would simply write:

fprintf(file, "%10p %10p / %5d %d\n", it->addr, it->pc, it->off, it->layout);
amaurea
  • 4,950
  • 26
  • 35
  • But I am looking for solution with `<<` – mahmood Oct 31 '12 at 13:57
  • Very well. But in general it is good to remember that you have the whole `C` toolbox available, and be pragmatic in using the one best suited for the task, and not being fundamentalist in sticking with the `C++`-only subset. – amaurea Oct 31 '12 at 14:00
1

When in doubt, use more setw! Also, you can use setfill to make the numbers look prettier:

std::cout << "0x"
          << std::hex << std::setfill('0') << std::setw(10) << (*it).addr
          << std::setw(5) << std::setfill(' ') << "0x"
          << std::hex << std::setfill('0') << std::setw(10) << (*it).pc
          << std::setw(10) << std::setfill(' ') << "/"
          << std::dec << std::setw(5) << (*it).off
          << std::setw(33) << (*it).layout
          << std::endl;

Produces:

0x0029823d80   0x00010019b8         /    0 00000000000000000000000000000001
0x0037449e60   0x0000010dfc         /   12 00000000000000000001000000000000
Xymostech
  • 9,710
  • 3
  • 34
  • 44