如何从 uint32_t 打印十六进制?

问题描述 投票:0回答:2

我一直在编写的代码要求我以十六进制打印一个

uint32_t
类型的变量,填充为0,最小长度为8。到目前为止,我用来执行此操作的代码是:

printf("%08lx\n",read_word(address));

其中 read_word 返回 uint32_t 类型。我用过jx、llx等格式都没有用,有没有正确的格式可以用?

编辑:

我发现问题出在我所传递的内容上。函数 read_word 从 uint32_t 向量返回一个值。看来这是导致十六进制输出问题的问题。这是引用/值传递问题吗?解决方法是什么?

read_word函数:

uint32_t memory::read_word (uint32_t address) {
  if(address>(maxWord)){
        return 0;
    }

    return mem[address];

}

内存减速度:

std::vector<uint32_t> mem=decltype(mem)(1024,0);
c++ c printf unsigned uint32-t
2个回答
14
投票

要在 C++ 中执行此操作,您需要滥用填充和宽度操纵器:

#include <iostream>
#include <iomanip>
#include <cstdint>

int main()
{
    uint32_t myInt = 123456;
    std::cout << std::setfill('0') << std::setw(8) << std::hex << myInt << '\n';
}

输出

0001e240

对于 C 来说,它变得更钝一些。你用

inttypes.h

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>


int main()
{
    uint32_t myInt = 123456;
    printf("%08" PRIx32 "\n", myInt);
    return 0;
}

输出

0001e240

请注意,在 C 中,

inttypes.h
中的常量与语言字符串连接功能一起使用,以形成所需的格式说明符。您只需提供零填充和最小长度作为序言。


3
投票

C++20

std::format
GCC 13,CLANG 14

这是现在 C++ 最干净的方法,因为它不会用

std::cout
和其他说明符污染
std::hex
状态:

主.cpp

#include <format>
#include <iostream>

int main() {
    std::cout << "0123456789" << std::endl;
    std::cout << std::format("{:#010x}", 17) << std::endl;
    std::cout << std::format("{:08x}", 17) << std::endl;
}

输出:

0123456789
0x00000011
00000011

在 GCC 13.2.0、Ubuntu 24.04 上测试。

记录于:

更多信息请访问:C++ cout 十六进制值?

libfmt-dev
:兼容库(如果您的 stdlib 还没有
std::format

libfmt-dev
是一个非常棒的库,后来成为了 C++20
std::format
,所以如果您的 C++ 标准库还没有该功能,您还可以:

sudo apt install libfmt-dev

或:

git clone https://github.com/fmtlib/fmt
cd fmt
git checkout 061e364b25b5e5ca7cf50dd25282892922375ddc
mkdir build
cmake ..
sudo make install

main2.cpp

#include <fmt/core.h>
#include <iostream>

int main() {
    std::cout << "0123456789" << std::endl;
    std::cout << fmt::format("{:#010x}", 17) << std::endl;
    std::cout << fmt::format("{:08x}", 17) << std::endl;
}

编译并运行:

g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main2.out main2.cpp -lfmt
./main2.out

在 GCC 10.0.1、Ubuntu 20.04 上测试。

C++20 之前版本,没有额外的库:干净地打印并恢复

std::cout
到之前的状态

如果你没有

std::format
并且无法使用
libfmt-dev
,我会这样做:

主.cpp

#include <iomanip>
#include <iostream>
#include <string>

int main() {
    std::ios oldState(nullptr);
    oldState.copyfmt(std::cout);
    std::cout << std::hex;
    std::cout << std::setfill('0');
    std::cout << std::setw(8);
    std::cout << 16 << std::endl;
    std::cout.copyfmt(oldState);
    std::cout << 17 << std::endl;
}

编译并运行:

g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out

输出:

00000010
17

更多细节:操作后恢复 std::cout 的状态

在 GCC 10.0.1、Ubuntu 20.04 上测试。

© www.soinside.com 2019 - 2024. All rights reserved.