我如何将字节打印为十六进制?

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

我知道您可以使用string.format方法。但是,您如何在C ++中执行此操作?是否可以使我可以将字节转换为十六进制?只需要将8个字节长的数据转换为十六进制,我该怎么做?

c++ arrays type-conversion data-conversion
8个回答
79
投票
如果您想使用C ++流而不是C函数,则可以执行以下操作:

int ar[] = { 20, 30, 40, 50, 60, 70, 80, 90 }; const int siz_ar = sizeof(ar) / sizeof(int); for (int i = 0; i < siz_ar; ++i) cout << ar[i] << " "; cout << endl; for (int i = 0; i < siz_ar; ++i) cout << hex << setfill('0') << setw(2) << ar[i] << " "; cout << endl;

非常简单

输出:

20 30 40 50 60 70 80 90 14 1e 28 32 3c 46 50 5a

well您可以将一个字节(未签名的char)转换为So

40
投票
char buffer [17]; buffer[16] = 0; for(j = 0; j < 8; j++) sprintf(&buffer[2*j], "%02X", data[j]);

您可以使用C ++ 20

23
投票

来完成,这与C#中的String.Format

std::string s = std::format("{:x}", std::byte(42)); // s == 2a
相似:
std::format

ultil
std::format

可广泛可用。

std::string s = fmt::format("{:x}", std::byte(42)); // s == 2a
Hint:如果您想要固定宽度,则零填充:
std::string s = fmt::format("{:02x}", std::byte(42));
disclaimer

:我是{fmt}和c ++ 20
std::format
的作者

C:

static void print_buf(const char *title, const unsigned char *buf, size_t buf_len) { size_t i = 0; fprintf(stdout, "%s\n", title); for(i = 0; i < buf_len; ++i) fprintf(stdout, "%02X%s", buf[i], ( i + 1 ) % 16 == 0 ? "\r\n" : " " ); } C++:


void print_bytes(std::ostream& out, const char *title, const unsigned char *data, size_t dataLen, bool format = true) { out << title << std::endl; out << std::setfill('0'); for(size_t i = 0; i < dataLen; ++i) { out << std::hex << std::setw(2) << (int)data[i]; if (format) { out << (((i + 1) % 16 == 0) ? "\n" : " "); } } out << std::endl; }


21
投票

在现代C ++中打印任意结构 到目前为止,所有答案都只能告诉您如何打印整数数组,但是鉴于我们知道它的大小,我们也可以打印任何任意结构。下面的示例创建了这样的结构,并通过其字节迭代指针,将其打印到输出:

#include <iostream>
#include <iomanip>
#include <cstring>

using std::cout;
using std::endl;
using std::hex;
using std::setfill;
using std::setw;

using u64 = unsigned long long;
using u16 = unsigned short;
using f64 = double;

struct Header {
    u16 version;
    u16 msgSize;
};

struct Example {
    Header header;
    u64 someId;
    u64 anotherId;
    bool isFoo;
    bool isBar;
    f64 floatingPointValue;
};

int main () {
    Example example;
    // fill with zeros so padding regions don't contain garbage
    memset(&example, 0, sizeof(Example));
    example.header.version = 5;
    example.header.msgSize = sizeof(Example) - sizeof(Header);
    example.someId = 0x1234;
    example.anotherId = 0x5678;
    example.isFoo = true;
    example.isBar = true;
    example.floatingPointValue = 1.1;

    cout << hex << setfill('0');  // needs to be set only once
    auto *ptr = reinterpret_cast<unsigned char *>(&example);
    for (int i = 0; i < sizeof(Example); i++, ptr++) {
        if (i % sizeof(u64) == 0) {
            cout << endl;
        }
        cout << setw(2) << static_cast<unsigned>(*ptr) << " ";
    }

    return 0;
}

这是输出:

05 00 24 00 00 00 00 00 
34 12 00 00 00 00 00 00 
78 56 00 00 00 00 00 00 
01 01 00 00 00 00 00 00 
9a 99 99 99 99 99 f1 3f

12
投票
记忆对齐

工作。我们看到

version

占据了2个字节(

05 00
),然后再添加2个字节(
msgSize

),然后是4个字节的填充物,之后又来了

24 00
someId

)和34 12 00 00 00 00 00 00

anotherId
)。然后,另一个字节(另一个字节)占据了1个字节(
78 56 00 00 00 00 00 00
),然后是6个字节的填充物,最后以IEEE 754 Double Field in的标准表示结束。

也请注意,所有值均表示为
小调(最不重要的字节首先),因为这是在Intel平台上编译并运行的。
    
这是nibble到十六进制方法的修改版本

isFoo
    
我不知道一个更好的方法:

01

您可以使用nibble对十六进制方法
加快速度

isBar
    

使用C ++流并恢复状态之后

这是我如何将字节打印为十六进制的变体?


4
投票
comestestion认为这会改变cout的状态,并试图在以下要求的结尾处恢复它:

main.cpp

01

3
投票
行和运行:

floatingPointValue

输出:

void hexArrayToStr(unsigned char* info, unsigned int infoLength, char **buffer) { const char* pszNibbleToHex = {"0123456789ABCDEF"}; int nNibble, i; if (infoLength > 0) { if (info != NULL) { *buffer = (char *) malloc((infoLength * 2) + 1); buffer[0][(infoLength * 2)] = 0; for (i = 0; i < infoLength; i++) { nNibble = info[i] >> 4; buffer[0][2 * i] = pszNibbleToHex[nNibble]; nNibble = info[i] & 0x0F; buffer[0][2 * i + 1] = pszNibbleToHex[nNibble]; } } else { *buffer = NULL; } } else { *buffer = NULL; } }

在Ubuntu 16.04,GCC6.4.0.
进行测试。

1
投票
另一个答案,如果字节数组定义为

unsigned char byData[xxx]; int nLength = sizeof(byData) * 2; char *pBuffer = new char[nLength + 1]; pBuffer[nLength] = 0; for (int i = 0; i < sizeof(byData); i++) { sprintf(pBuffer[2 * i], "%02X", byData[i]); } ,大写,并被空间隔开。 unsigned char byData[xxx]; const char szNibbleToHex = { "0123456789ABCDEF" }; int nLength = sizeof(byData) * 2; char *pBuffer = new char[nLength + 1]; pBuffer[nLength] = 0; for (int i = 0; i < sizeof(byData); i++) { // divide by 16 int nNibble = byData[i] >> 4; pBuffer[2 * i] = pszNibbleToHex[nNibble]; nNibble = byData[i] & 0x0F; pBuffer[2 * i + 1] = pszNibbleToHex[nNibble]; }

示例: #include <iomanip> #include <iostream> int main() { int array[] = {0, 0x8, 0x10, 0x18}; constexpr size_t size = sizeof(array) / sizeof(array[0]); // Sanity check decimal print. for (size_t i = 0; i < size; ++i) std::cout << array[i] << " "; std::cout << std::endl; // Hex print and restore default afterwards. std::ios cout_state(nullptr); cout_state.copyfmt(std::cout); std::cout << std::hex << std::setfill('0') << std::setw(2); for (size_t i = 0; i < size; ++i) std::cout << array[i] << " "; std::cout << std::endl; std::cout.copyfmt(cout_state); // Check that cout state was restored. for (size_t i = 0; i < size; ++i) std::cout << array[i] << " "; std::cout << std::endl; }

    输出:
  • g++ -o main.out -std=c++11 main.cpp ./main.out
另一个c ++ 17替代方案,因为为什么不!

0 8 16 24 00 8 10 18 0 8 16 24

可启用代码
hereY.


最新问题
© www.soinside.com 2019 - 2024. All rights reserved.