c++ - hex << setw() << setfill() 不适用于指针值输出

标签 c++ formatting

Win7 - 64
cygwin
Netbeans 7.4
gcc (cygwin) 4.8.3

编译器调用

g++ -Wall -Wno-reorder -Wno-unused-value -c -g -MMD -MP -MF

输出和预期输出不同的原因是什么?我没想到“0x”前缀。

Output   << SlipHashEntry::create      0x22a000 list3
Expected << SlipHashEntry::create      0x000000000022a000 list3

Output   << SlipDescription::delete    0x600062d50 list5
Expected << SlipDescription::delete    0x0000000600062d50 list5

这是相关的代码片段

SlipHashEntry::SlipHashEntry
    ( const string& name, void* ptr, Type type, int debugFlag )
: completeFlag(false)
, debugFlag(debugFlag)
, hashDebugFlag((bool)(debugFlag & SlipRead::HASH))
, inputDebugFlag((bool)(debugFlag & SlipRead::INPUT))
, leakDebugFlag((bool)(debugFlag & SlipRead::LEAK))
, descriptorChain(NULL)
, link(NULL)
, name(new string(name))
, nestedPtr(NULL)
, ptr(ptr)
, type(type) { 
    DEBUG(leakDebugFlag,
    cout << left << setw(27) << setfill(' ') << "SlipHashEntry::create " 
         << hex << setw(sizeof(void*)) 
         << setfill('0') << (void*)this << ' ' << name <<endl;)
}; 

最佳答案

"Any reason that the output and the expected output are different? I did not expect the "0x" prefix."

关于 0x输出中的前缀,这是由 std::ostream& operator<<(std::ostream&, const void*) see (7) 的内部运算符重载完成的

你对setw()也有一点误解: 你应该记住,setw()以字符(即数字)为单位设置字段大小。你想显示一个 64 位的指针,相当于 8 个字节,每个字节用 2 位数字表示

      cout << left << setw(27) << setfill(' ') << "SlipHashEntry::create " 
           << hex << setw(2 * sizeof(void*)) 
                       // ^^^
           << setfill('0') << (void*)this << ' ' << name <<endl;)

只需将指针大小(以字节为单位)乘以 2,即可获得完整数字的正确字段宽度。

虽然 void* 的固有输出运算符定义并不完全符合您的要求。
当我试图为我上面所说的内容制作一个在线可编译示例时,我注意到您实际上无法操作内部指针输出格式。我做了一个简单的例子,如何实现你想要的固定8字节格式:

#include <iostream>
#include <iomanip>

// A simple manipulator to format pointers in a fixed length format (according 
// 64 bit) with leading zeroes and a "0x" prefix
class fmt_longptr {
public:
    fmt_longptr(void* ptr) : ptr_(ptr) {}
    void put(std::ostream& os) const {
        os << "0x" << std::hex << std::setw(2 * sizeof(void*)) 
           << std::setfill('0') << (unsigned long)ptr_;
    }
private:
    friend std::ostream& operator<<(std::ostream& os, const fmt_longptr& fmt);
    void* ptr_;
};

std::ostream& operator<<(std::ostream& os, const fmt_longptr& fmt) {
    fmt.put(os);
    return os;
}

下面是它的使用方法,并展示了与内部指针格式的区别

int main() {
    int a;

    std::cout << std::setfill('0') << std::setw(2 * sizeof(void*)) << &a 
              << std::endl;
    std::cout << fmt_longptr(&a) << std::endl;
    return 0;
}

输出

000x7fff270d987c
0x00007fff270d987c

这是 working online sample .

关于c++ - hex << setw() << setfill() 不适用于指针值输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24700442/

相关文章:

c++ - ncurses:奇怪的行格式

c++ - c++ 局部类中的静态成员变量?

dart - 如何为矩阵制作Dartfmt “friendly”?

c# - FormattedText Width 属性不考虑尾随空格

android - 如何在 Android Studio 中格式化评论?

c++ - 确定一个点是否在任意数量的框中的最有效方法是什么

c++ - 通过 boost append 到现有文件

c++ - h.264字节流解析

python - 如何在没有任何额外符号(方括号 [] 和元素之间的空格)的情况下打印 Numpy 数组?

C#:在 RichTextBox 中粘贴 RTF,但保留颜色和格式(即:粗体、下划线等)