解析二进制文件时,如何在“court”中将整数变量显示为预期的 ASCII 字母?
How can I display an integer variable as thier intended ASCII letters in `cout` when parsing a binary file?
当我在命令行上使用 hexdump -C
检查这个 MIDI 文件时,我们可以看到这个二进制文件的一些字节是 ASCII 字母,这些字母是人类可读的文本。
00000000 4d 54 68 64 00 00 00 06 00 01 00 08 00 78 4d 54 |MThd.........xMT|
000024f0 2f 00 4d 54 72 6b 00 00 00 19 00 ff 21 01 00 00 |/.MTrk......!...|
00002500 ff 03 0c 62 79 20 42 65 65 74 68 6f 76 65 6e 00 |...by Beethoven.|
00002510 ff 2f 00 4d 54 72 6b 00 00 00 18 00 ff 21 01 00 |./.MTrk......!..|
出于调试目的,当我有一个变量保存一个我知道代表一串 ASCII 字符的整数时,我想简单地在 cout
.
中显示 ASCII 字符
在这种情况下,文件的前四个字节是 0x4d546864
,代表字母 MThd
.
uint32_t n32Bits = 0;
ifs.read((char*)&n32Bits, sizeof(uint32_t));
n32Bits = BigEndianToLittleEndian(n32Bits); // reverse byte order
这是整数:
std::cout << "n32Bits: " << n32Bits <<std::endl; // 1297377380
我可以轻松地将其显示为十六进制:
std::cout << "n32Bits: " << std::hex << n32Bits <<std::endl; // 4d546864
现在,我希望这一行像 hexdump
一样输出字母 MThd
。:
std::cout << "n32Bits: " << std::ascii << n32Bits <<std::endl; // compile error.
没有一些简单的内置方法可以从表示 ASCII 字母的整数中转储 ASCII 字母吗?
没有像 std::ascii
这样的格式规范,但是有一个 string
构造函数可以使用:
std::string int2str((char*)&n32Bits, 4);
std::cout << "n32Bits: " << int2str << std::endl;
此构造函数采用 char
缓冲区和长度。
int a = 0x4d546864;
// swap_bytes(a);
int b[] = {a, 0};
cout << (char*)b <<endl;
没有像十六进制转储那样将原始字节打印为 ASCII 字符串的内置函数。您必须自己手动执行此操作,例如:
#include <algorithm>
#include <iterator>
#include <cctype>
#include <cstring>
char buffer[sizeof(n32Bits)];
std::memcpy(buffer, &n32Bits, sizeof(n32Bits));
std::transform(std::begin(buffer), std::end(buffer), std::begin(buffer),
[](unsigned char ch){ return std::isprint(ch) ? static_cast<char>(ch) : '.'; }
);
std::cout << "n32Bits: ";
std::cout.write(buffer, sizeof(buffer));
std::cout << std::endl;
当我在命令行上使用 hexdump -C
检查这个 MIDI 文件时,我们可以看到这个二进制文件的一些字节是 ASCII 字母,这些字母是人类可读的文本。
00000000 4d 54 68 64 00 00 00 06 00 01 00 08 00 78 4d 54 |MThd.........xMT|
000024f0 2f 00 4d 54 72 6b 00 00 00 19 00 ff 21 01 00 00 |/.MTrk......!...|
00002500 ff 03 0c 62 79 20 42 65 65 74 68 6f 76 65 6e 00 |...by Beethoven.|
00002510 ff 2f 00 4d 54 72 6b 00 00 00 18 00 ff 21 01 00 |./.MTrk......!..|
出于调试目的,当我有一个变量保存一个我知道代表一串 ASCII 字符的整数时,我想简单地在 cout
.
在这种情况下,文件的前四个字节是 0x4d546864
,代表字母 MThd
.
uint32_t n32Bits = 0;
ifs.read((char*)&n32Bits, sizeof(uint32_t));
n32Bits = BigEndianToLittleEndian(n32Bits); // reverse byte order
这是整数:
std::cout << "n32Bits: " << n32Bits <<std::endl; // 1297377380
我可以轻松地将其显示为十六进制:
std::cout << "n32Bits: " << std::hex << n32Bits <<std::endl; // 4d546864
现在,我希望这一行像 hexdump
一样输出字母 MThd
。:
std::cout << "n32Bits: " << std::ascii << n32Bits <<std::endl; // compile error.
没有一些简单的内置方法可以从表示 ASCII 字母的整数中转储 ASCII 字母吗?
没有像 std::ascii
这样的格式规范,但是有一个 string
构造函数可以使用:
std::string int2str((char*)&n32Bits, 4);
std::cout << "n32Bits: " << int2str << std::endl;
此构造函数采用 char
缓冲区和长度。
int a = 0x4d546864;
// swap_bytes(a);
int b[] = {a, 0};
cout << (char*)b <<endl;
没有像十六进制转储那样将原始字节打印为 ASCII 字符串的内置函数。您必须自己手动执行此操作,例如:
#include <algorithm>
#include <iterator>
#include <cctype>
#include <cstring>
char buffer[sizeof(n32Bits)];
std::memcpy(buffer, &n32Bits, sizeof(n32Bits));
std::transform(std::begin(buffer), std::end(buffer), std::begin(buffer),
[](unsigned char ch){ return std::isprint(ch) ? static_cast<char>(ch) : '.'; }
);
std::cout << "n32Bits: ";
std::cout.write(buffer, sizeof(buffer));
std::cout << std::endl;