justify text with setw

2019-07-31 15:32发布

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 

标签: c++ setw
3条回答
我命由我不由天
2楼-- · 2019-07-31 15:52

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.

查看更多
forever°为你锁心
3楼-- · 2019-07-31 15:52

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);
查看更多
4楼-- · 2019-07-31 15:54

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
查看更多
登录 后发表回答