Search code examples
c++setw

justify text with setw


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 

Solution

  • 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.