使用二进制文件读取和打印二进制数据C++
Reading & printing binary data as it is from a binary file using C++
如何读取二进制文件(我不知道它的类型或存储在其中的内容)并将0
s和1
s打印到文本文件中?
#include <iostream>
#include <fstream>
#include <string.h>
#include <iomanip>
using namespace std;
int main(int argc, char *argv[])
{
char ch;
bool x;
int i = 0;
if (argc < 3)
{
cout << endl << "Please put in all parameters" << endl;
return 0;
}
char *c = new char[4];
ifstream fin(argv[1], ios_base::in | ios_base::binary);
if (!fin.is_open())
{
cout << "Error opening input file" << endl;
return 0;
}
if (!strcmp(argv[2], "-file"))
{
ofstream fout(argv[3]);
if (!fout.is_open())
{
cout << "Error opening output file" << endl;
return 0;
}
while (fin.read(c, sizeof ch))
{
fout << c;
}
cout << "Contents written to file successfully" << endl;
fout.close();
}
else if (!strcmp(argv[2], "-screen"))
{
cout << endl << "Contents of the file: " << endl;
while (fin.read((char *)&x,sizeof x))
{
cout << x;
}
cout << endl;
}
else
{
cout << endl << "Please input correct option" << endl;
return 0;
}
fin.close();
return 0;
}
是的,只需使用fstreams并打开带有二进制标志的文件,然后您就可以像普通的fstream一样处理资源并将其流式传输到文本文件中。如果你想把0和1转换成字符那就有点复杂了。最简单的方法很可能是像这样用无符号字符缓冲字节,然后尝试通过sprintf.
操作它们。 fstream APIsprintf API
无论好坏,我发现printf
最容易完成:
#include <fstream>
#include <cstdio>
static const std::size_t blocks = 256;
char buf[blocks * 16];
std::ifstream infile(filename, "rb");
do
{
infile.read(buf, blocks * 16);
for (std::size_t i = 0; i * 16 < infile.gcount(); ++i)
{
for (std::size_t j = 0; j < 16 && 16 * i + j < infile.gcount(); ++j)
{
if (j != 0) std::printf(" ");
std::printf("0x%02X", static_cast<unsigned char>(buf[16 * i + j]));
}
}
} while (infile);
我选择了任意的行长度,每行16字节,我一次读取4kiB——这可以调优以获得最大的效率。使用gcount()
来获取实际的读取字节数是很重要的,因为最后一轮循环的读取可能少于4kiB。
注意,这在本质上相当于hexdump
实用程序。
如果需要实际的二进制输出,可以编写一个小的辅助例程来代替printf
。
正如我所得到的,您不需要十六进制输出,而是二进制(0和1),尽管我不明白为什么。没有io操纵符输出二进制数据。您需要使用位操作符自己完成此操作。像这样:
char c; // contains byte read from input
for (size_t i = 0; i != sizeof(c); ++i) {
std::cout << c & 0x80; // grab most significant bit
c <<= 1; // right shift by 1 bit
}
最简单的方法可能是从输入创建一个std::bitset
,并将它们打印出来。忽略错误检查等,一个简单的版本会像这样出现:
#include <bitset>
#include <fstream>
#include <iostream>
#include <ios>
#include <iomanip>
int main(int argc, char **argv) {
std::ifstream infile(argv[1], std::ios::binary);
char ch;
unsigned long count = 0;
while (infile.read(&ch, 1)) {
if (count++ % 4 == 0)
std::cout << "n" << std::setw(6) << std::hex << count;
std::cout << std::setw(10) << std::bitset<8>(ch);
}
return 0;
}
我认为十六进制的正常转储更有用。我在上面每行只显示4个字节(如果省略行首的偏移量,8个字节将适合80列,这将是一个严重的损失,至少在我的经验中),因此整个屏幕通常只有~200字节左右。在十六进制中,您可以(并且通常会)每行显示16字节,包括十六进制和(对于可打印字符)本身。
我应该补充一点,然而,我已经使用十六进制转储几十年了,所以我的观点可能至少部分是基于偏见,而不是真实的事实。
相关文章:
- 如何从dicom文件中读取二进制数据
- 如何在Qt中从数据库中检索二进制数据?
- readsome() 适合在 Windows 上读取二进制数据吗?
- 如何使用 redis-plus-plus 存储二进制数据,就像我想存储结构一样?@for_stack?
- 将包含二进制数据的 QByteArray 传递到按值运行
- 如何在 c++ 中生成十六进制二进制数据的 sha256 哈希?
- 在处理网络、二进制数据和序列化时应使用流或容器
- 我能确定从文件中读取的 32 字节二进制数据等于 256 位吗?
- C++:如何通过 curl 调用使用 HTTP post 请求发送二进制数据(protobuf 数据)
- 使用二进制数据更新 PostgreSQL 表
- 使用二进制数据和无符号字符
- sd_journal_send发送二进制数据.如何使用日志检索数据?
- 从带有 std::ifstream::read() 的文件中读取 int 遍历 char * 二进制数据
- 将文本和二进制数据连接到一个文件中
- 二进制模式 + 格式化文本操作或文本模式 + 二进制数据操作 - 有意义吗?
- 将整数的二进制数据转换为浮点数
- 使用 CMake 在可执行文件中嵌入二进制数据
- 二进制数据作为命令行参数
- 如何访问文件的二进制数据?
- 返回二进制数据的通用方式,而无需原始指针