简体   繁体   English

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

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

I have a printf statement as:我有一个 printf 语句为:

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

How do I write this statement using std::cout ?如何使用std::cout编写此语句? Buffer variables contains huge addresses.缓冲区变量包含巨大的地址。

You can use the std::setw , std::setfill and std::hex modifiers:您可以使用std::setwstd::setfillstd::hex修饰符:

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

Notes:笔记:

  • std::setw resets after printing something std::setw打印后重置
  • As noted by Tarang Jain , std::showbase would place the base marker inside the filling (ie 000xDEAD instead of 0x0000DEAD ) so I edited this answer to reflect this.正如 Tarang Jain所指出的, std::showbase会将基本标记放置在填充物内(即000xDEAD而不是0x0000DEAD )所以我编辑了这个答案以反映这一点。
  • You may need to #include <iomanip>您可能需要#include <iomanip>
  • It may be a good idea to wrap this iomanips between std::ios_base::fmtflags f{cout.flags()};std::ios_base::fmtflags f{cout.flags()};之间包装这个 iomanips 可能是个好主意。 to save the flags and cout.flags(f);保存标志和cout.flags(f); to reset them to their former values, see this question for more information要将它们重置为以前的值,请参阅此问题以获取更多信息
  • This answer provides a way to display things using iomanips, see also Jerry Coffin's answer to simply print a memory address此答案提供了一种使用 iomanips 显示内容的方法,另请参阅Jerry Coffin 的答案,以简单地打印 memory 地址

A more complete example, using an object to leverage RAII to clear the flags更完整的示例,使用 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);

  // ...
}

What you're doing in C is (apparently) casting the pointers to an unsigned integer type, then printing out that value in hexadecimal.您在 C 中所做的(显然)将指针转换为无符号 integer 类型,然后以十六进制打印出该值。

C++, however, provides a conversion specifically for pointers:然而,C++ 提供了专门针对指针的转换:

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

On most typical current implementations, this will probably produce pretty much the same result (ie, an unsigned number in hexadecimal, probably zero-filled to produce the width of the addressing on the target system).在大多数典型的当前实现中,这可能会产生几乎相同的结果(即,十六进制的无符号数,可能用零填充以产生目标系统上的寻址宽度)。

Since this is more abstract, it can adapt to the conventions of the target system.由于这更抽象,它可以适应目标系统的约定。 One target system might normally omit the leading 0x .一个目标系统通常可能会省略前导0x Another might normally use octal instead of hexadecimal.另一个可能通常使用八进制而不是十六进制。 And, of course, it won't usually print out a 64-bit address on a system that uses 32-bit addressing.当然,它通常不会在使用 32 位寻址的系统上打印出 64 位地址。 Instead, this can produce the accepted convention on the system you target, instead of your explicitly specifying one convention that happens to match the systems to which you're accustomed.相反,这可以在您的目标系统上产生公认的约定,而不是您明确指定一个恰好与您习惯的系统匹配的约定。

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

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