简体   繁体   中英

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

I have a printf statement as:

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 ? Buffer variables contains huge addresses.

You can use the std::setw , std::setfill and std::hex modifiers:

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

Notes:

  • std::setw resets after printing something
  • 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.
  • You may need to #include <iomanip>
  • It may be a good idea to wrap this iomanips between std::ios_base::fmtflags f{cout.flags()}; to save the flags and 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

A more complete example, using an object to leverage RAII to clear the flags

#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++, however, provides a conversion specifically for pointers:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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