justify text with setw

2019-07-31 15:54发布

问题:

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 

回答1:

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.



回答2:

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);


回答3:

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


标签: c++ setw