繁体   English   中英

printf 语句中的 0x%08lx 格式说明符到 cout

[英]0x%08lx format specifier in printf statement to cout

我有一个 printf 语句为:

printf("Buffer A Data: 0x%08lx, Buffer B Data: 0x%08lx\n\n", (ul) bufa, (ul) bufb);

如何使用std::cout编写此语句? 缓冲区变量包含巨大的地址。

您可以使用std::setwstd::setfillstd::hex修饰符:

std::cout << "0x" << std::hex << std::setw(8) << std::setfill('0') << bufa;

笔记:

  • std::setw打印后重置
  • 正如 Tarang Jain所指出的, std::showbase会将基本标记放置在填充物内(即000xDEAD而不是0x0000DEAD )所以我编辑了这个答案以反映这一点。
  • 您可能需要#include <iomanip>
  • std::ios_base::fmtflags f{cout.flags()};之间包装这个 iomanips 可能是个好主意。 保存标志和cout.flags(f); 要将它们重置为以前的值,请参阅此问题以获取更多信息
  • 此答案提供了一种使用 iomanips 显示内容的方法,另请参阅Jerry Coffin 的答案,以简单地打印 memory 地址

更完整的示例,使用 object 来利用RAII清除标志

#include <iomanip>
#include <ostream>

struct addressPrinter
{
  addressPrinter(std::ostream& out)
  : out{out}, flags{out.flags()}
  {
  }

  ~addressPrinter()
  {
    out.flags(flags);
  }

  void print(unsigned long address)
  {
    out << "0x" << std::hex << std::setw(8) << std::setfill('0') << address;
  }

  std::ostream& out;
  std::ios_base::fmtflags flags;
};

void foo()
{
  // ...

  addressPrinter printer{std::cout};

  printer.print(bufa);
  printer.print(bufb);

  // ...
}

您在 C 中所做的(显然)将指针转换为无符号 integer 类型,然后以十六进制打印出该值。

然而,C++ 提供了专门针对指针的转换:

std::cout << "Buffer A Data: " << static_cast<void *>(bufa) 
          << ", Buffer B Data: " << static_cast<void *>(bufb) << "\n\n";

在大多数典型的当前实现中,这可能会产生几乎相同的结果(即,十六进制的无符号数,可能用零填充以产生目标系统上的寻址宽度)。

由于这更抽象,它可以适应目标系统的约定。 一个目标系统通常可能会省略前导0x 另一个可能通常使用八进制而不是十六进制。 当然,它通常不会在使用 32 位寻址的系统上打印出 64 位地址。 相反,这可以在您的目标系统上产生公认的约定,而不是您明确指定一个恰好与您习惯的系统匹配的约定。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM